sequence.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  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(from uint32) (uint32, uint32, error) {
  78. if s.block == blockMAX || s.count == 0 {
  79. return invalidPos, invalidPos, errNoBitAvailable
  80. }
  81. bits := from
  82. bitSel := blockFirstBit >> from
  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. // SetAnyInRange atomically sets the first unset bit in the specified range in the sequence and returns the corresponding ordinal
  167. func (h *Handle) SetAnyInRange(start, end uint32) (uint32, error) {
  168. if end-start <= 0 || end >= h.bits {
  169. return invalidPos, fmt.Errorf("invalid bit range [%d, %d]", start, end)
  170. }
  171. if h.Unselected() == 0 {
  172. return invalidPos, errNoBitAvailable
  173. }
  174. return h.set(0, start, end, true, false)
  175. }
  176. // SetAny atomically sets the first unset bit in the sequence and returns the corresponding ordinal
  177. func (h *Handle) SetAny() (uint32, error) {
  178. if h.Unselected() == 0 {
  179. return invalidPos, errNoBitAvailable
  180. }
  181. return h.set(0, 0, h.bits-1, true, false)
  182. }
  183. // Set atomically sets the corresponding bit in the sequence
  184. func (h *Handle) Set(ordinal uint32) error {
  185. if err := h.validateOrdinal(ordinal); err != nil {
  186. return err
  187. }
  188. _, err := h.set(ordinal, 0, 0, false, false)
  189. return err
  190. }
  191. // Unset atomically unsets the corresponding bit in the sequence
  192. func (h *Handle) Unset(ordinal uint32) error {
  193. if err := h.validateOrdinal(ordinal); err != nil {
  194. return err
  195. }
  196. _, err := h.set(ordinal, 0, 0, false, true)
  197. return err
  198. }
  199. // IsSet atomically checks if the ordinal bit is set. In case ordinal
  200. // is outside of the bit sequence limits, false is returned.
  201. func (h *Handle) IsSet(ordinal uint32) bool {
  202. if err := h.validateOrdinal(ordinal); err != nil {
  203. return false
  204. }
  205. h.Lock()
  206. _, _, err := checkIfAvailable(h.head, ordinal)
  207. h.Unlock()
  208. return err != nil
  209. }
  210. // set/reset the bit
  211. func (h *Handle) set(ordinal, start, end uint32, any bool, release bool) (uint32, error) {
  212. var (
  213. bitPos uint32
  214. bytePos uint32
  215. ret uint32
  216. err error
  217. )
  218. for {
  219. h.Lock()
  220. // Get position if available
  221. if release {
  222. bytePos, bitPos = ordinalToPos(ordinal)
  223. } else {
  224. if any {
  225. bytePos, bitPos, err = getFirstAvailable(h.head, start)
  226. ret = posToOrdinal(bytePos, bitPos)
  227. if end < ret {
  228. err = errNoBitAvailable
  229. }
  230. } else {
  231. bytePos, bitPos, err = checkIfAvailable(h.head, ordinal)
  232. ret = ordinal
  233. }
  234. }
  235. if err != nil {
  236. h.Unlock()
  237. return ret, err
  238. }
  239. // Create a private copy of h and work on it
  240. nh := h.getCopy()
  241. h.Unlock()
  242. nh.head = pushReservation(bytePos, bitPos, nh.head, release)
  243. if release {
  244. nh.unselected++
  245. } else {
  246. nh.unselected--
  247. }
  248. // Attempt to write private copy to store
  249. if err := nh.writeToStore(); err != nil {
  250. if _, ok := err.(types.RetryError); !ok {
  251. return ret, fmt.Errorf("internal failure while setting the bit: %v", err)
  252. }
  253. // Retry
  254. continue
  255. }
  256. // Previous atomic push was succesfull. Save private copy to local copy
  257. h.Lock()
  258. defer h.Unlock()
  259. h.unselected = nh.unselected
  260. h.head = nh.head
  261. h.dbExists = nh.dbExists
  262. h.dbIndex = nh.dbIndex
  263. return ret, nil
  264. }
  265. }
  266. // checks is needed because to cover the case where the number of bits is not a multiple of blockLen
  267. func (h *Handle) validateOrdinal(ordinal uint32) error {
  268. if ordinal >= h.bits {
  269. return fmt.Errorf("bit does not belong to the sequence")
  270. }
  271. return nil
  272. }
  273. // Destroy removes from the datastore the data belonging to this handle
  274. func (h *Handle) Destroy() error {
  275. for {
  276. if err := h.deleteFromStore(); err != nil {
  277. if _, ok := err.(types.RetryError); !ok {
  278. return fmt.Errorf("internal failure while destroying the sequence: %v", err)
  279. }
  280. // Fetch latest
  281. if err := h.store.GetObject(datastore.Key(h.Key()...), h); err != nil {
  282. if err == datastore.ErrKeyNotFound { // already removed
  283. return nil
  284. }
  285. return fmt.Errorf("failed to fetch from store when destroying the sequence: %v", err)
  286. }
  287. continue
  288. }
  289. return nil
  290. }
  291. }
  292. // ToByteArray converts this handle's data into a byte array
  293. func (h *Handle) ToByteArray() ([]byte, error) {
  294. h.Lock()
  295. defer h.Unlock()
  296. ba := make([]byte, 8)
  297. binary.BigEndian.PutUint32(ba[0:], h.bits)
  298. binary.BigEndian.PutUint32(ba[4:], h.unselected)
  299. bm, err := h.head.toByteArray()
  300. if err != nil {
  301. return nil, fmt.Errorf("failed to serialize head: %s", err.Error())
  302. }
  303. ba = append(ba, bm...)
  304. return ba, nil
  305. }
  306. // FromByteArray reads his handle's data from a byte array
  307. func (h *Handle) FromByteArray(ba []byte) error {
  308. if ba == nil {
  309. return fmt.Errorf("nil byte array")
  310. }
  311. nh := &sequence{}
  312. err := nh.fromByteArray(ba[8:])
  313. if err != nil {
  314. return fmt.Errorf("failed to deserialize head: %s", err.Error())
  315. }
  316. h.Lock()
  317. h.head = nh
  318. h.bits = binary.BigEndian.Uint32(ba[0:4])
  319. h.unselected = binary.BigEndian.Uint32(ba[4:8])
  320. h.Unlock()
  321. return nil
  322. }
  323. // Bits returns the length of the bit sequence
  324. func (h *Handle) Bits() uint32 {
  325. return h.bits
  326. }
  327. // Unselected returns the number of bits which are not selected
  328. func (h *Handle) Unselected() uint32 {
  329. h.Lock()
  330. defer h.Unlock()
  331. return h.unselected
  332. }
  333. func (h *Handle) String() string {
  334. h.Lock()
  335. defer h.Unlock()
  336. return fmt.Sprintf("App: %s, ID: %s, DBIndex: 0x%x, bits: %d, unselected: %d, sequence: %s",
  337. h.app, h.id, h.dbIndex, h.bits, h.unselected, h.head.toString())
  338. }
  339. // getFirstAvailable looks for the first unset bit in passed mask starting from start
  340. func getFirstAvailable(head *sequence, start uint32) (uint32, uint32, error) {
  341. // Find sequence which contains the start bit
  342. byteStart, bitStart := ordinalToPos(start)
  343. current, _, _, inBlockBytePos := findSequence(head, byteStart)
  344. // Derive the this sequence offsets
  345. byteOffset := byteStart - inBlockBytePos
  346. bitOffset := inBlockBytePos*8 + bitStart
  347. for current != nil {
  348. if current.block != blockMAX {
  349. bytePos, bitPos, err := current.getAvailableBit(bitOffset)
  350. return byteOffset + bytePos, bitPos, err
  351. }
  352. // Moving to next block: Reset bit offset.
  353. bitOffset = 0
  354. byteOffset += current.count * blockBytes
  355. current = current.next
  356. }
  357. return invalidPos, invalidPos, errNoBitAvailable
  358. }
  359. // checkIfAvailable checks if the bit correspondent to the specified ordinal is unset
  360. // If the ordinal is beyond the sequence limits, a negative response is returned
  361. func checkIfAvailable(head *sequence, ordinal uint32) (uint32, uint32, error) {
  362. bytePos, bitPos := ordinalToPos(ordinal)
  363. // Find the sequence containing this byte
  364. current, _, _, inBlockBytePos := findSequence(head, bytePos)
  365. if current != nil {
  366. // Check whether the bit corresponding to the ordinal address is unset
  367. bitSel := blockFirstBit >> (inBlockBytePos*8 + bitPos)
  368. if current.block&bitSel == 0 {
  369. return bytePos, bitPos, nil
  370. }
  371. }
  372. return invalidPos, invalidPos, fmt.Errorf("requested bit is not available")
  373. }
  374. // Given the byte position and the sequences list head, return the pointer to the
  375. // sequence containing the byte (current), the pointer to the previous sequence,
  376. // the number of blocks preceding the block containing the byte inside the current sequence.
  377. // If bytePos is outside of the list, function will return (nil, nil, 0, invalidPos)
  378. func findSequence(head *sequence, bytePos uint32) (*sequence, *sequence, uint32, uint32) {
  379. // Find the sequence containing this byte
  380. previous := head
  381. current := head
  382. n := bytePos
  383. for current.next != nil && n >= (current.count*blockBytes) { // Nil check for less than 32 addresses masks
  384. n -= (current.count * blockBytes)
  385. previous = current
  386. current = current.next
  387. }
  388. // If byte is outside of the list, let caller know
  389. if n >= (current.count * blockBytes) {
  390. return nil, nil, 0, invalidPos
  391. }
  392. // Find the byte position inside the block and the number of blocks
  393. // preceding the block containing the byte inside this sequence
  394. precBlocks := n / blockBytes
  395. inBlockBytePos := bytePos % blockBytes
  396. return current, previous, precBlocks, inBlockBytePos
  397. }
  398. // PushReservation pushes the bit reservation inside the bitmask.
  399. // Given byte and bit positions, identify the sequence (current) which holds the block containing the affected bit.
  400. // Create a new block with the modified bit according to the operation (allocate/release).
  401. // Create a new sequence containing the new block and insert it in the proper position.
  402. // Remove current sequence if empty.
  403. // Check if new sequence can be merged with neighbour (previous/next) sequences.
  404. //
  405. //
  406. // Identify "current" sequence containing block:
  407. // [prev seq] [current seq] [next seq]
  408. //
  409. // Based on block position, resulting list of sequences can be any of three forms:
  410. //
  411. // block position Resulting list of sequences
  412. // A) block is first in current: [prev seq] [new] [modified current seq] [next seq]
  413. // B) block is last in current: [prev seq] [modified current seq] [new] [next seq]
  414. // C) block is in the middle of current: [prev seq] [curr pre] [new] [curr post] [next seq]
  415. func pushReservation(bytePos, bitPos uint32, head *sequence, release bool) *sequence {
  416. // Store list's head
  417. newHead := head
  418. // Find the sequence containing this byte
  419. current, previous, precBlocks, inBlockBytePos := findSequence(head, bytePos)
  420. if current == nil {
  421. return newHead
  422. }
  423. // Construct updated block
  424. bitSel := blockFirstBit >> (inBlockBytePos*8 + bitPos)
  425. newBlock := current.block
  426. if release {
  427. newBlock &^= bitSel
  428. } else {
  429. newBlock |= bitSel
  430. }
  431. // Quit if it was a redundant request
  432. if current.block == newBlock {
  433. return newHead
  434. }
  435. // Current sequence inevitably looses one block, upadate count
  436. current.count--
  437. // Create new sequence
  438. newSequence := &sequence{block: newBlock, count: 1}
  439. // Insert the new sequence in the list based on block position
  440. if precBlocks == 0 { // First in sequence (A)
  441. newSequence.next = current
  442. if current == head {
  443. newHead = newSequence
  444. previous = newHead
  445. } else {
  446. previous.next = newSequence
  447. }
  448. removeCurrentIfEmpty(&newHead, newSequence, current)
  449. mergeSequences(previous)
  450. } else if precBlocks == current.count-2 { // Last in sequence (B)
  451. newSequence.next = current.next
  452. current.next = newSequence
  453. mergeSequences(current)
  454. } else { // In between the sequence (C)
  455. currPre := &sequence{block: current.block, count: precBlocks, next: newSequence}
  456. currPost := current
  457. currPost.count -= precBlocks
  458. newSequence.next = currPost
  459. if currPost == head {
  460. newHead = currPre
  461. } else {
  462. previous.next = currPre
  463. }
  464. // No merging or empty current possible here
  465. }
  466. return newHead
  467. }
  468. // Removes the current sequence from the list if empty, adjusting the head pointer if needed
  469. func removeCurrentIfEmpty(head **sequence, previous, current *sequence) {
  470. if current.count == 0 {
  471. if current == *head {
  472. *head = current.next
  473. } else {
  474. previous.next = current.next
  475. current = current.next
  476. }
  477. }
  478. }
  479. // Given a pointer to a sequence, it checks if it can be merged with any following sequences
  480. // It stops when no more merging is possible.
  481. // TODO: Optimization: only attempt merge from start to end sequence, no need to scan till the end of the list
  482. func mergeSequences(seq *sequence) {
  483. if seq != nil {
  484. // Merge all what possible from seq
  485. for seq.next != nil && seq.block == seq.next.block {
  486. seq.count += seq.next.count
  487. seq.next = seq.next.next
  488. }
  489. // Move to next
  490. mergeSequences(seq.next)
  491. }
  492. }
  493. func getNumBlocks(numBits uint32) uint32 {
  494. numBlocks := numBits / blockLen
  495. if numBits%blockLen != 0 {
  496. numBlocks++
  497. }
  498. return numBlocks
  499. }
  500. func ordinalToPos(ordinal uint32) (uint32, uint32) {
  501. return ordinal / 8, ordinal % 8
  502. }
  503. func posToOrdinal(bytePos, bitPos uint32) uint32 {
  504. return bytePos*8 + bitPos
  505. }