sequence.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  1. // Package bitseq provides a structure and utilities for representing long bitmask
  2. // as sequence of run-lenght encoded blocks. It operates direclty on the encoded
  3. // representation, it does not decode/encode.
  4. package bitseq
  5. import (
  6. "encoding/binary"
  7. "fmt"
  8. "sync"
  9. "github.com/docker/libnetwork/datastore"
  10. "github.com/docker/libnetwork/types"
  11. )
  12. // block sequence constants
  13. // If needed we can think of making these configurable
  14. const (
  15. blockLen = uint32(32)
  16. blockBytes = blockLen / 8
  17. blockMAX = uint32(1<<blockLen - 1)
  18. blockFirstBit = uint32(1) << (blockLen - 1)
  19. invalidPos = blockMAX
  20. )
  21. var (
  22. errNoBitAvailable = fmt.Errorf("no bit available")
  23. )
  24. // Handle contains the sequece representing the bitmask and its identifier
  25. type Handle struct {
  26. bits uint32
  27. unselected uint32
  28. head *sequence
  29. app string
  30. id string
  31. dbIndex uint64
  32. dbExists bool
  33. store datastore.DataStore
  34. sync.Mutex
  35. }
  36. // NewHandle returns a thread-safe instance of the bitmask handler
  37. func NewHandle(app string, ds datastore.DataStore, id string, numElements uint32) (*Handle, error) {
  38. h := &Handle{
  39. app: app,
  40. id: id,
  41. store: ds,
  42. bits: numElements,
  43. unselected: numElements,
  44. head: &sequence{
  45. block: 0x0,
  46. count: getNumBlocks(numElements),
  47. },
  48. }
  49. if h.store == nil {
  50. return h, nil
  51. }
  52. // Register for status changes
  53. h.watchForChanges()
  54. // Get the initial status from the ds if present.
  55. if err := h.store.GetObject(datastore.Key(h.Key()...), h); err != nil && err != datastore.ErrKeyNotFound {
  56. return nil, err
  57. }
  58. return h, nil
  59. }
  60. // sequence represents a recurring sequence of 32 bits long bitmasks
  61. type sequence struct {
  62. block uint32 // block is a symbol representing 4 byte long allocation bitmask
  63. count uint32 // number of consecutive blocks (symbols)
  64. next *sequence // next sequence
  65. }
  66. // String returns a string representation of the block sequence starting from this block
  67. func (s *sequence) toString() string {
  68. var nextBlock string
  69. if s.next == nil {
  70. nextBlock = "end"
  71. } else {
  72. nextBlock = s.next.toString()
  73. }
  74. return fmt.Sprintf("(0x%x, %d)->%s", s.block, s.count, nextBlock)
  75. }
  76. // GetAvailableBit returns the position of the first unset bit in the bitmask represented by this sequence
  77. func (s *sequence) getAvailableBit() (uint32, uint32, error) {
  78. if s.block == blockMAX || s.count == 0 {
  79. return invalidPos, invalidPos, fmt.Errorf("no available bit")
  80. }
  81. bits := uint32(0)
  82. bitSel := blockFirstBit
  83. for bitSel > 0 && s.block&bitSel != 0 {
  84. bitSel >>= 1
  85. bits++
  86. }
  87. return bits / 8, bits % 8, nil
  88. }
  89. // GetCopy returns a copy of the linked list rooted at this node
  90. func (s *sequence) getCopy() *sequence {
  91. n := &sequence{block: s.block, count: s.count}
  92. pn := n
  93. ps := s.next
  94. for ps != nil {
  95. pn.next = &sequence{block: ps.block, count: ps.count}
  96. pn = pn.next
  97. ps = ps.next
  98. }
  99. return n
  100. }
  101. // Equal checks if this sequence is equal to the passed one
  102. func (s *sequence) equal(o *sequence) bool {
  103. this := s
  104. other := o
  105. for this != nil {
  106. if other == nil {
  107. return false
  108. }
  109. if this.block != other.block || this.count != other.count {
  110. return false
  111. }
  112. this = this.next
  113. other = other.next
  114. }
  115. // Check if other is longer than this
  116. if other != nil {
  117. return false
  118. }
  119. return true
  120. }
  121. // ToByteArray converts the sequence into a byte array
  122. func (s *sequence) toByteArray() ([]byte, error) {
  123. var bb []byte
  124. p := s
  125. for p != nil {
  126. b := make([]byte, 8)
  127. binary.BigEndian.PutUint32(b[0:], p.block)
  128. binary.BigEndian.PutUint32(b[4:], p.count)
  129. bb = append(bb, b...)
  130. p = p.next
  131. }
  132. return bb, nil
  133. }
  134. // fromByteArray construct the sequence from the byte array
  135. func (s *sequence) fromByteArray(data []byte) error {
  136. l := len(data)
  137. if l%8 != 0 {
  138. return fmt.Errorf("cannot deserialize byte sequence of lenght %d (%v)", l, data)
  139. }
  140. p := s
  141. i := 0
  142. for {
  143. p.block = binary.BigEndian.Uint32(data[i : i+4])
  144. p.count = binary.BigEndian.Uint32(data[i+4 : i+8])
  145. i += 8
  146. if i == l {
  147. break
  148. }
  149. p.next = &sequence{}
  150. p = p.next
  151. }
  152. return nil
  153. }
  154. func (h *Handle) getCopy() *Handle {
  155. return &Handle{
  156. bits: h.bits,
  157. unselected: h.unselected,
  158. head: h.head.getCopy(),
  159. app: h.app,
  160. id: h.id,
  161. dbIndex: h.dbIndex,
  162. dbExists: h.dbExists,
  163. store: h.store,
  164. }
  165. }
  166. // SetAny atomically sets the first unset bit in the sequence and returns the corresponding ordinal
  167. func (h *Handle) SetAny() (uint32, error) {
  168. if h.Unselected() == 0 {
  169. return invalidPos, errNoBitAvailable
  170. }
  171. return h.set(0, true, false)
  172. }
  173. // Set atomically sets the corresponding bit in the sequence
  174. func (h *Handle) Set(ordinal uint32) error {
  175. if err := h.validateOrdinal(ordinal); err != nil {
  176. return err
  177. }
  178. _, err := h.set(ordinal, false, false)
  179. return err
  180. }
  181. // Unset atomically unsets the corresponding bit in the sequence
  182. func (h *Handle) Unset(ordinal uint32) error {
  183. if err := h.validateOrdinal(ordinal); err != nil {
  184. return err
  185. }
  186. _, err := h.set(ordinal, false, true)
  187. return err
  188. }
  189. // IsSet atomically checks if the ordinal bit is set. In case ordinal
  190. // is outside of the bit sequence limits, false is returned.
  191. func (h *Handle) IsSet(ordinal uint32) bool {
  192. if err := h.validateOrdinal(ordinal); err != nil {
  193. return false
  194. }
  195. h.Lock()
  196. _, _, err := checkIfAvailable(h.head, ordinal)
  197. h.Unlock()
  198. return err != nil
  199. }
  200. // set/reset the bit
  201. func (h *Handle) set(ordinal uint32, any bool, release bool) (uint32, error) {
  202. var (
  203. bitPos uint32
  204. bytePos uint32
  205. ret uint32
  206. err error
  207. )
  208. for {
  209. h.Lock()
  210. // Get position if available
  211. if release {
  212. bytePos, bitPos = ordinalToPos(ordinal)
  213. } else {
  214. if any {
  215. bytePos, bitPos, err = getFirstAvailable(h.head)
  216. ret = posToOrdinal(bytePos, bitPos)
  217. } else {
  218. bytePos, bitPos, err = checkIfAvailable(h.head, ordinal)
  219. ret = ordinal
  220. }
  221. }
  222. if err != nil {
  223. h.Unlock()
  224. return ret, err
  225. }
  226. // Create a private copy of h and work on it, also copy the current db index
  227. nh := h.getCopy()
  228. ci := h.dbIndex
  229. h.Unlock()
  230. nh.head = pushReservation(bytePos, bitPos, nh.head, release)
  231. if release {
  232. nh.unselected++
  233. } else {
  234. nh.unselected--
  235. }
  236. // Attempt to write private copy to store
  237. if err := nh.writeToStore(); err != nil {
  238. if _, ok := err.(types.RetryError); !ok {
  239. return ret, fmt.Errorf("internal failure while setting the bit: %v", err)
  240. }
  241. // Retry
  242. continue
  243. }
  244. // Unless unexpected error, save private copy to local copy
  245. h.Lock()
  246. defer h.Unlock()
  247. if h.dbIndex != ci {
  248. return ret, fmt.Errorf("unexected database index change")
  249. }
  250. h.unselected = nh.unselected
  251. h.head = nh.head
  252. h.dbExists = nh.dbExists
  253. h.dbIndex = nh.dbIndex
  254. return ret, nil
  255. }
  256. }
  257. // checks is needed because to cover the case where the number of bits is not a multiple of blockLen
  258. func (h *Handle) validateOrdinal(ordinal uint32) error {
  259. if ordinal > h.bits {
  260. return fmt.Errorf("bit does not belong to the sequence")
  261. }
  262. return nil
  263. }
  264. // Destroy removes from the datastore the data belonging to this handle
  265. func (h *Handle) Destroy() {
  266. h.deleteFromStore()
  267. }
  268. // ToByteArray converts this handle's data into a byte array
  269. func (h *Handle) ToByteArray() ([]byte, error) {
  270. h.Lock()
  271. defer h.Unlock()
  272. ba := make([]byte, 8)
  273. binary.BigEndian.PutUint32(ba[0:], h.bits)
  274. binary.BigEndian.PutUint32(ba[4:], h.unselected)
  275. bm, err := h.head.toByteArray()
  276. if err != nil {
  277. return nil, fmt.Errorf("failed to serialize head: %s", err.Error())
  278. }
  279. ba = append(ba, bm...)
  280. return ba, nil
  281. }
  282. // FromByteArray reads his handle's data from a byte array
  283. func (h *Handle) FromByteArray(ba []byte) error {
  284. if ba == nil {
  285. return fmt.Errorf("nil byte array")
  286. }
  287. nh := &sequence{}
  288. err := nh.fromByteArray(ba[8:])
  289. if err != nil {
  290. return fmt.Errorf("failed to deserialize head: %s", err.Error())
  291. }
  292. h.Lock()
  293. h.head = nh
  294. h.bits = binary.BigEndian.Uint32(ba[0:4])
  295. h.unselected = binary.BigEndian.Uint32(ba[4:8])
  296. h.Unlock()
  297. return nil
  298. }
  299. // Bits returns the length of the bit sequence
  300. func (h *Handle) Bits() uint32 {
  301. return h.bits
  302. }
  303. // Unselected returns the number of bits which are not selected
  304. func (h *Handle) Unselected() uint32 {
  305. h.Lock()
  306. defer h.Unlock()
  307. return h.unselected
  308. }
  309. func (h *Handle) String() string {
  310. h.Lock()
  311. defer h.Unlock()
  312. return fmt.Sprintf("App: %s, ID: %s, DBIndex: 0x%x, bits: %d, unselected: %d, sequence: %s",
  313. h.app, h.id, h.dbIndex, h.bits, h.unselected, h.head.toString())
  314. }
  315. // getFirstAvailable looks for the first unset bit in passed mask
  316. func getFirstAvailable(head *sequence) (uint32, uint32, error) {
  317. byteIndex := uint32(0)
  318. current := head
  319. for current != nil {
  320. if current.block != blockMAX {
  321. bytePos, bitPos, err := current.getAvailableBit()
  322. return byteIndex + bytePos, bitPos, err
  323. }
  324. byteIndex += current.count * blockBytes
  325. current = current.next
  326. }
  327. return invalidPos, invalidPos, errNoBitAvailable
  328. }
  329. // checkIfAvailable checks if the bit correspondent to the specified ordinal is unset
  330. // If the ordinal is beyond the sequence limits, a negative response is returned
  331. func checkIfAvailable(head *sequence, ordinal uint32) (uint32, uint32, error) {
  332. bytePos := ordinal / 8
  333. bitPos := ordinal % 8
  334. // Find the sequence containing this byte
  335. current, _, _, inBlockBytePos := findSequence(head, bytePos)
  336. if current != nil {
  337. // Check whether the bit corresponding to the ordinal address is unset
  338. bitSel := blockFirstBit >> (inBlockBytePos*8 + bitPos)
  339. if current.block&bitSel == 0 {
  340. return bytePos, bitPos, nil
  341. }
  342. }
  343. return invalidPos, invalidPos, fmt.Errorf("requested bit is not available")
  344. }
  345. // Given the byte position and the sequences list head, return the pointer to the
  346. // sequence containing the byte (current), the pointer to the previous sequence,
  347. // the number of blocks preceding the block containing the byte inside the current sequence.
  348. // If bytePos is outside of the list, function will return (nil, nil, 0, invalidPos)
  349. func findSequence(head *sequence, bytePos uint32) (*sequence, *sequence, uint32, uint32) {
  350. // Find the sequence containing this byte
  351. previous := head
  352. current := head
  353. n := bytePos
  354. for current.next != nil && n >= (current.count*blockBytes) { // Nil check for less than 32 addresses masks
  355. n -= (current.count * blockBytes)
  356. previous = current
  357. current = current.next
  358. }
  359. // If byte is outside of the list, let caller know
  360. if n >= (current.count * blockBytes) {
  361. return nil, nil, 0, invalidPos
  362. }
  363. // Find the byte position inside the block and the number of blocks
  364. // preceding the block containing the byte inside this sequence
  365. precBlocks := n / blockBytes
  366. inBlockBytePos := bytePos % blockBytes
  367. return current, previous, precBlocks, inBlockBytePos
  368. }
  369. // PushReservation pushes the bit reservation inside the bitmask.
  370. // Given byte and bit positions, identify the sequence (current) which holds the block containing the affected bit.
  371. // Create a new block with the modified bit according to the operation (allocate/release).
  372. // Create a new sequence containing the new block and insert it in the proper position.
  373. // Remove current sequence if empty.
  374. // Check if new sequence can be merged with neighbour (previous/next) sequences.
  375. //
  376. //
  377. // Identify "current" sequence containing block:
  378. // [prev seq] [current seq] [next seq]
  379. //
  380. // Based on block position, resulting list of sequences can be any of three forms:
  381. //
  382. // block position Resulting list of sequences
  383. // A) block is first in current: [prev seq] [new] [modified current seq] [next seq]
  384. // B) block is last in current: [prev seq] [modified current seq] [new] [next seq]
  385. // C) block is in the middle of current: [prev seq] [curr pre] [new] [curr post] [next seq]
  386. func pushReservation(bytePos, bitPos uint32, head *sequence, release bool) *sequence {
  387. // Store list's head
  388. newHead := head
  389. // Find the sequence containing this byte
  390. current, previous, precBlocks, inBlockBytePos := findSequence(head, bytePos)
  391. if current == nil {
  392. return newHead
  393. }
  394. // Construct updated block
  395. bitSel := blockFirstBit >> (inBlockBytePos*8 + bitPos)
  396. newBlock := current.block
  397. if release {
  398. newBlock &^= bitSel
  399. } else {
  400. newBlock |= bitSel
  401. }
  402. // Quit if it was a redundant request
  403. if current.block == newBlock {
  404. return newHead
  405. }
  406. // Current sequence inevitably looses one block, upadate count
  407. current.count--
  408. // Create new sequence
  409. newSequence := &sequence{block: newBlock, count: 1}
  410. // Insert the new sequence in the list based on block position
  411. if precBlocks == 0 { // First in sequence (A)
  412. newSequence.next = current
  413. if current == head {
  414. newHead = newSequence
  415. previous = newHead
  416. } else {
  417. previous.next = newSequence
  418. }
  419. removeCurrentIfEmpty(&newHead, newSequence, current)
  420. mergeSequences(previous)
  421. } else if precBlocks == current.count-2 { // Last in sequence (B)
  422. newSequence.next = current.next
  423. current.next = newSequence
  424. mergeSequences(current)
  425. } else { // In between the sequence (C)
  426. currPre := &sequence{block: current.block, count: precBlocks, next: newSequence}
  427. currPost := current
  428. currPost.count -= precBlocks
  429. newSequence.next = currPost
  430. if currPost == head {
  431. newHead = currPre
  432. } else {
  433. previous.next = currPre
  434. }
  435. // No merging or empty current possible here
  436. }
  437. return newHead
  438. }
  439. // Removes the current sequence from the list if empty, adjusting the head pointer if needed
  440. func removeCurrentIfEmpty(head **sequence, previous, current *sequence) {
  441. if current.count == 0 {
  442. if current == *head {
  443. *head = current.next
  444. } else {
  445. previous.next = current.next
  446. current = current.next
  447. }
  448. }
  449. }
  450. // Given a pointer to a sequence, it checks if it can be merged with any following sequences
  451. // It stops when no more merging is possible.
  452. // TODO: Optimization: only attempt merge from start to end sequence, no need to scan till the end of the list
  453. func mergeSequences(seq *sequence) {
  454. if seq != nil {
  455. // Merge all what possible from seq
  456. for seq.next != nil && seq.block == seq.next.block {
  457. seq.count += seq.next.count
  458. seq.next = seq.next.next
  459. }
  460. // Move to next
  461. mergeSequences(seq.next)
  462. }
  463. }
  464. func getNumBlocks(numBits uint32) uint32 {
  465. numBlocks := numBits / blockLen
  466. if numBits%blockLen != 0 {
  467. numBlocks++
  468. }
  469. return numBlocks
  470. }
  471. func ordinalToPos(ordinal uint32) (uint32, uint32) {
  472. return ordinal / 8, ordinal % 8
  473. }
  474. func posToOrdinal(bytePos, bitPos uint32) uint32 {
  475. return bytePos*8 + bitPos
  476. }