sequence.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  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() {
  275. h.deleteFromStore()
  276. }
  277. // ToByteArray converts this handle's data into a byte array
  278. func (h *Handle) ToByteArray() ([]byte, error) {
  279. h.Lock()
  280. defer h.Unlock()
  281. ba := make([]byte, 8)
  282. binary.BigEndian.PutUint32(ba[0:], h.bits)
  283. binary.BigEndian.PutUint32(ba[4:], h.unselected)
  284. bm, err := h.head.toByteArray()
  285. if err != nil {
  286. return nil, fmt.Errorf("failed to serialize head: %s", err.Error())
  287. }
  288. ba = append(ba, bm...)
  289. return ba, nil
  290. }
  291. // FromByteArray reads his handle's data from a byte array
  292. func (h *Handle) FromByteArray(ba []byte) error {
  293. if ba == nil {
  294. return fmt.Errorf("nil byte array")
  295. }
  296. nh := &sequence{}
  297. err := nh.fromByteArray(ba[8:])
  298. if err != nil {
  299. return fmt.Errorf("failed to deserialize head: %s", err.Error())
  300. }
  301. h.Lock()
  302. h.head = nh
  303. h.bits = binary.BigEndian.Uint32(ba[0:4])
  304. h.unselected = binary.BigEndian.Uint32(ba[4:8])
  305. h.Unlock()
  306. return nil
  307. }
  308. // Bits returns the length of the bit sequence
  309. func (h *Handle) Bits() uint32 {
  310. return h.bits
  311. }
  312. // Unselected returns the number of bits which are not selected
  313. func (h *Handle) Unselected() uint32 {
  314. h.Lock()
  315. defer h.Unlock()
  316. return h.unselected
  317. }
  318. func (h *Handle) String() string {
  319. h.Lock()
  320. defer h.Unlock()
  321. return fmt.Sprintf("App: %s, ID: %s, DBIndex: 0x%x, bits: %d, unselected: %d, sequence: %s",
  322. h.app, h.id, h.dbIndex, h.bits, h.unselected, h.head.toString())
  323. }
  324. // getFirstAvailable looks for the first unset bit in passed mask starting from start
  325. func getFirstAvailable(head *sequence, start uint32) (uint32, uint32, error) {
  326. // Find sequence which contains the start bit
  327. byteStart, bitStart := ordinalToPos(start)
  328. current, _, _, inBlockBytePos := findSequence(head, byteStart)
  329. // Derive the this sequence offsets
  330. byteOffset := byteStart - inBlockBytePos
  331. bitOffset := inBlockBytePos*8 + bitStart
  332. for current != nil {
  333. if current.block != blockMAX {
  334. bytePos, bitPos, err := current.getAvailableBit(bitOffset)
  335. return byteOffset + bytePos, bitPos, err
  336. }
  337. // Moving to next block: Reset bit offset.
  338. bitOffset = 0
  339. byteOffset += current.count * blockBytes
  340. current = current.next
  341. }
  342. return invalidPos, invalidPos, errNoBitAvailable
  343. }
  344. // checkIfAvailable checks if the bit correspondent to the specified ordinal is unset
  345. // If the ordinal is beyond the sequence limits, a negative response is returned
  346. func checkIfAvailable(head *sequence, ordinal uint32) (uint32, uint32, error) {
  347. bytePos, bitPos := ordinalToPos(ordinal)
  348. // Find the sequence containing this byte
  349. current, _, _, inBlockBytePos := findSequence(head, bytePos)
  350. if current != nil {
  351. // Check whether the bit corresponding to the ordinal address is unset
  352. bitSel := blockFirstBit >> (inBlockBytePos*8 + bitPos)
  353. if current.block&bitSel == 0 {
  354. return bytePos, bitPos, nil
  355. }
  356. }
  357. return invalidPos, invalidPos, fmt.Errorf("requested bit is not available")
  358. }
  359. // Given the byte position and the sequences list head, return the pointer to the
  360. // sequence containing the byte (current), the pointer to the previous sequence,
  361. // the number of blocks preceding the block containing the byte inside the current sequence.
  362. // If bytePos is outside of the list, function will return (nil, nil, 0, invalidPos)
  363. func findSequence(head *sequence, bytePos uint32) (*sequence, *sequence, uint32, uint32) {
  364. // Find the sequence containing this byte
  365. previous := head
  366. current := head
  367. n := bytePos
  368. for current.next != nil && n >= (current.count*blockBytes) { // Nil check for less than 32 addresses masks
  369. n -= (current.count * blockBytes)
  370. previous = current
  371. current = current.next
  372. }
  373. // If byte is outside of the list, let caller know
  374. if n >= (current.count * blockBytes) {
  375. return nil, nil, 0, invalidPos
  376. }
  377. // Find the byte position inside the block and the number of blocks
  378. // preceding the block containing the byte inside this sequence
  379. precBlocks := n / blockBytes
  380. inBlockBytePos := bytePos % blockBytes
  381. return current, previous, precBlocks, inBlockBytePos
  382. }
  383. // PushReservation pushes the bit reservation inside the bitmask.
  384. // Given byte and bit positions, identify the sequence (current) which holds the block containing the affected bit.
  385. // Create a new block with the modified bit according to the operation (allocate/release).
  386. // Create a new sequence containing the new block and insert it in the proper position.
  387. // Remove current sequence if empty.
  388. // Check if new sequence can be merged with neighbour (previous/next) sequences.
  389. //
  390. //
  391. // Identify "current" sequence containing block:
  392. // [prev seq] [current seq] [next seq]
  393. //
  394. // Based on block position, resulting list of sequences can be any of three forms:
  395. //
  396. // block position Resulting list of sequences
  397. // A) block is first in current: [prev seq] [new] [modified current seq] [next seq]
  398. // B) block is last in current: [prev seq] [modified current seq] [new] [next seq]
  399. // C) block is in the middle of current: [prev seq] [curr pre] [new] [curr post] [next seq]
  400. func pushReservation(bytePos, bitPos uint32, head *sequence, release bool) *sequence {
  401. // Store list's head
  402. newHead := head
  403. // Find the sequence containing this byte
  404. current, previous, precBlocks, inBlockBytePos := findSequence(head, bytePos)
  405. if current == nil {
  406. return newHead
  407. }
  408. // Construct updated block
  409. bitSel := blockFirstBit >> (inBlockBytePos*8 + bitPos)
  410. newBlock := current.block
  411. if release {
  412. newBlock &^= bitSel
  413. } else {
  414. newBlock |= bitSel
  415. }
  416. // Quit if it was a redundant request
  417. if current.block == newBlock {
  418. return newHead
  419. }
  420. // Current sequence inevitably looses one block, upadate count
  421. current.count--
  422. // Create new sequence
  423. newSequence := &sequence{block: newBlock, count: 1}
  424. // Insert the new sequence in the list based on block position
  425. if precBlocks == 0 { // First in sequence (A)
  426. newSequence.next = current
  427. if current == head {
  428. newHead = newSequence
  429. previous = newHead
  430. } else {
  431. previous.next = newSequence
  432. }
  433. removeCurrentIfEmpty(&newHead, newSequence, current)
  434. mergeSequences(previous)
  435. } else if precBlocks == current.count-2 { // Last in sequence (B)
  436. newSequence.next = current.next
  437. current.next = newSequence
  438. mergeSequences(current)
  439. } else { // In between the sequence (C)
  440. currPre := &sequence{block: current.block, count: precBlocks, next: newSequence}
  441. currPost := current
  442. currPost.count -= precBlocks
  443. newSequence.next = currPost
  444. if currPost == head {
  445. newHead = currPre
  446. } else {
  447. previous.next = currPre
  448. }
  449. // No merging or empty current possible here
  450. }
  451. return newHead
  452. }
  453. // Removes the current sequence from the list if empty, adjusting the head pointer if needed
  454. func removeCurrentIfEmpty(head **sequence, previous, current *sequence) {
  455. if current.count == 0 {
  456. if current == *head {
  457. *head = current.next
  458. } else {
  459. previous.next = current.next
  460. current = current.next
  461. }
  462. }
  463. }
  464. // Given a pointer to a sequence, it checks if it can be merged with any following sequences
  465. // It stops when no more merging is possible.
  466. // TODO: Optimization: only attempt merge from start to end sequence, no need to scan till the end of the list
  467. func mergeSequences(seq *sequence) {
  468. if seq != nil {
  469. // Merge all what possible from seq
  470. for seq.next != nil && seq.block == seq.next.block {
  471. seq.count += seq.next.count
  472. seq.next = seq.next.next
  473. }
  474. // Move to next
  475. mergeSequences(seq.next)
  476. }
  477. }
  478. func getNumBlocks(numBits uint32) uint32 {
  479. numBlocks := numBits / blockLen
  480. if numBits%blockLen != 0 {
  481. numBlocks++
  482. }
  483. return numBlocks
  484. }
  485. func ordinalToPos(ordinal uint32) (uint32, uint32) {
  486. return ordinal / 8, ordinal % 8
  487. }
  488. func posToOrdinal(bytePos, bitPos uint32) uint32 {
  489. return bytePos*8 + bitPos
  490. }