sequence.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  1. // Package bitmap provides a datatype for long vectors of bits.
  2. package bitmap
  3. import (
  4. "encoding/binary"
  5. "encoding/json"
  6. "errors"
  7. "fmt"
  8. )
  9. // block sequence constants
  10. // If needed we can think of making these configurable
  11. const (
  12. blockLen = uint32(32)
  13. blockBytes = uint64(blockLen / 8)
  14. blockMAX = uint32(1<<blockLen - 1)
  15. blockFirstBit = uint32(1) << (blockLen - 1)
  16. invalidPos = uint64(0xFFFFFFFFFFFFFFFF)
  17. )
  18. var (
  19. // ErrNoBitAvailable is returned when no more bits are available to set
  20. ErrNoBitAvailable = errors.New("no bit available")
  21. // ErrBitAllocated is returned when the specific bit requested is already set
  22. ErrBitAllocated = errors.New("requested bit is already allocated")
  23. )
  24. // https://github.com/golang/go/issues/8005#issuecomment-190753527
  25. type noCopy struct{}
  26. func (noCopy) Lock() {}
  27. // Bitmap is a fixed-length bit vector. It is not safe for concurrent use.
  28. //
  29. // The data is stored as a list of run-length encoded blocks. It operates
  30. // directly on the encoded representation, without decompressing.
  31. type Bitmap struct {
  32. bits uint64
  33. unselected uint64
  34. head *sequence
  35. curr uint64
  36. // Shallow copies would share the same head pointer but a copy of the
  37. // unselected count. Mutating the sequence through one would change the
  38. // bits for all copies but only update that one copy's unselected count,
  39. // which would result in subtle bugs.
  40. noCopy noCopy
  41. }
  42. // NewHandle returns a new Bitmap n bits long.
  43. func New(n uint64) *Bitmap {
  44. return &Bitmap{
  45. bits: n,
  46. unselected: n,
  47. head: &sequence{
  48. block: 0x0,
  49. count: getNumBlocks(n),
  50. },
  51. }
  52. }
  53. // Copy returns a deep copy of b.
  54. func Copy(b *Bitmap) *Bitmap {
  55. return &Bitmap{
  56. bits: b.bits,
  57. unselected: b.unselected,
  58. head: b.head.getCopy(),
  59. curr: b.curr,
  60. }
  61. }
  62. // sequence represents a recurring sequence of 32 bits long bitmasks
  63. type sequence struct {
  64. block uint32 // block is a symbol representing 4 byte long allocation bitmask
  65. count uint64 // number of consecutive blocks (symbols)
  66. next *sequence // next sequence
  67. }
  68. // String returns a string representation of the block sequence starting from this block
  69. func (s *sequence) toString() string {
  70. var nextBlock string
  71. if s.next == nil {
  72. nextBlock = "end"
  73. } else {
  74. nextBlock = s.next.toString()
  75. }
  76. return fmt.Sprintf("(0x%x, %d)->%s", s.block, s.count, nextBlock)
  77. }
  78. // GetAvailableBit returns the position of the first unset bit in the bitmask represented by this sequence
  79. func (s *sequence) getAvailableBit(from uint64) (uint64, uint64, error) {
  80. if s.block == blockMAX || s.count == 0 {
  81. return invalidPos, invalidPos, ErrNoBitAvailable
  82. }
  83. bits := from
  84. bitSel := blockFirstBit >> from
  85. for bitSel > 0 && s.block&bitSel != 0 {
  86. bitSel >>= 1
  87. bits++
  88. }
  89. // Check if the loop exited because it could not
  90. // find any available bit int block starting from
  91. // "from". Return invalid pos in that case.
  92. if bitSel == 0 {
  93. return invalidPos, invalidPos, ErrNoBitAvailable
  94. }
  95. return bits / 8, bits % 8, nil
  96. }
  97. // GetCopy returns a copy of the linked list rooted at this node
  98. func (s *sequence) getCopy() *sequence {
  99. n := &sequence{block: s.block, count: s.count}
  100. pn := n
  101. ps := s.next
  102. for ps != nil {
  103. pn.next = &sequence{block: ps.block, count: ps.count}
  104. pn = pn.next
  105. ps = ps.next
  106. }
  107. return n
  108. }
  109. // Equal checks if this sequence is equal to the passed one
  110. func (s *sequence) equal(o *sequence) bool {
  111. this := s
  112. other := o
  113. for this != nil {
  114. if other == nil {
  115. return false
  116. }
  117. if this.block != other.block || this.count != other.count {
  118. return false
  119. }
  120. this = this.next
  121. other = other.next
  122. }
  123. return other == nil
  124. }
  125. // ToByteArray converts the sequence into a byte array
  126. func (s *sequence) toByteArray() ([]byte, error) {
  127. var bb []byte
  128. p := s
  129. for p != nil {
  130. b := make([]byte, 12)
  131. binary.BigEndian.PutUint32(b[0:], p.block)
  132. binary.BigEndian.PutUint64(b[4:], p.count)
  133. bb = append(bb, b...)
  134. p = p.next
  135. }
  136. return bb, nil
  137. }
  138. // fromByteArray construct the sequence from the byte array
  139. func (s *sequence) fromByteArray(data []byte) error {
  140. l := len(data)
  141. if l%12 != 0 {
  142. return fmt.Errorf("cannot deserialize byte sequence of length %d (%v)", l, data)
  143. }
  144. p := s
  145. i := 0
  146. for {
  147. p.block = binary.BigEndian.Uint32(data[i : i+4])
  148. p.count = binary.BigEndian.Uint64(data[i+4 : i+12])
  149. i += 12
  150. if i == l {
  151. break
  152. }
  153. p.next = &sequence{}
  154. p = p.next
  155. }
  156. return nil
  157. }
  158. // SetAnyInRange sets the first unset bit in the range [start, end) and returns
  159. // the ordinal of the set bit.
  160. //
  161. // When serial=true, the bitmap is scanned starting from the ordinal following
  162. // the bit most recently set by [Bitmap.SetAny] or [Bitmap.SetAnyInRange].
  163. func (h *Bitmap) SetAnyInRange(start, end uint64, serial bool) (uint64, error) {
  164. if end < start || end >= h.bits {
  165. return invalidPos, fmt.Errorf("invalid bit range [%d, %d)", start, end)
  166. }
  167. if h.Unselected() == 0 {
  168. return invalidPos, ErrNoBitAvailable
  169. }
  170. return h.set(0, start, end, true, false, serial)
  171. }
  172. // SetAny sets the first unset bit in the sequence and returns the ordinal of
  173. // the set bit.
  174. //
  175. // When serial=true, the bitmap is scanned starting from the ordinal following
  176. // the bit most recently set by [Bitmap.SetAny] or [Bitmap.SetAnyInRange].
  177. func (h *Bitmap) SetAny(serial bool) (uint64, error) {
  178. if h.Unselected() == 0 {
  179. return invalidPos, ErrNoBitAvailable
  180. }
  181. return h.set(0, 0, h.bits-1, true, false, serial)
  182. }
  183. // Set atomically sets the corresponding bit in the sequence
  184. func (h *Bitmap) Set(ordinal uint64) error {
  185. if err := h.validateOrdinal(ordinal); err != nil {
  186. return err
  187. }
  188. _, err := h.set(ordinal, 0, 0, false, false, false)
  189. return err
  190. }
  191. // Unset atomically unsets the corresponding bit in the sequence
  192. func (h *Bitmap) Unset(ordinal uint64) error {
  193. if err := h.validateOrdinal(ordinal); err != nil {
  194. return err
  195. }
  196. _, err := h.set(ordinal, 0, 0, false, true, false)
  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 *Bitmap) IsSet(ordinal uint64) bool {
  202. if err := h.validateOrdinal(ordinal); err != nil {
  203. return false
  204. }
  205. _, _, err := checkIfAvailable(h.head, ordinal)
  206. return err != nil
  207. }
  208. // CheckConsistency checks if the bit sequence is in an inconsistent state and attempts to fix it.
  209. // It looks for a corruption signature that may happen in docker 1.9.0 and 1.9.1.
  210. func (h *Bitmap) CheckConsistency() bool {
  211. corrupted := false
  212. for p, c := h.head, h.head.next; c != nil; c = c.next {
  213. if c.count == 0 {
  214. corrupted = true
  215. p.next = c.next
  216. continue // keep same p
  217. }
  218. p = c
  219. }
  220. return corrupted
  221. }
  222. // set/reset the bit
  223. func (h *Bitmap) set(ordinal, start, end uint64, any bool, release bool, serial bool) (uint64, error) {
  224. var (
  225. bitPos uint64
  226. bytePos uint64
  227. ret uint64
  228. err error
  229. )
  230. curr := uint64(0)
  231. if serial {
  232. curr = h.curr
  233. }
  234. // Get position if available
  235. if release {
  236. bytePos, bitPos = ordinalToPos(ordinal)
  237. } else {
  238. if any {
  239. bytePos, bitPos, err = getAvailableFromCurrent(h.head, start, curr, end)
  240. ret = posToOrdinal(bytePos, bitPos)
  241. if err == nil {
  242. h.curr = ret + 1
  243. }
  244. } else {
  245. bytePos, bitPos, err = checkIfAvailable(h.head, ordinal)
  246. ret = ordinal
  247. }
  248. }
  249. if err != nil {
  250. return ret, err
  251. }
  252. h.head = pushReservation(bytePos, bitPos, h.head, release)
  253. if release {
  254. h.unselected++
  255. } else {
  256. h.unselected--
  257. }
  258. return ret, nil
  259. }
  260. // checks is needed because to cover the case where the number of bits is not a multiple of blockLen
  261. func (h *Bitmap) validateOrdinal(ordinal uint64) error {
  262. if ordinal >= h.bits {
  263. return errors.New("bit does not belong to the sequence")
  264. }
  265. return nil
  266. }
  267. // MarshalBinary encodes h into a binary representation.
  268. func (h *Bitmap) MarshalBinary() ([]byte, error) {
  269. ba := make([]byte, 16)
  270. binary.BigEndian.PutUint64(ba[0:], h.bits)
  271. binary.BigEndian.PutUint64(ba[8:], h.unselected)
  272. bm, err := h.head.toByteArray()
  273. if err != nil {
  274. return nil, fmt.Errorf("failed to serialize head: %v", err)
  275. }
  276. ba = append(ba, bm...)
  277. return ba, nil
  278. }
  279. // UnmarshalBinary decodes a binary representation of a Bitmap value which was
  280. // generated using [Bitmap.MarshalBinary].
  281. //
  282. // The scan position for serial [Bitmap.SetAny] and [Bitmap.SetAnyInRange]
  283. // operations is neither unmarshaled nor reset.
  284. func (h *Bitmap) UnmarshalBinary(ba []byte) error {
  285. if ba == nil {
  286. return errors.New("nil byte array")
  287. }
  288. nh := &sequence{}
  289. err := nh.fromByteArray(ba[16:])
  290. if err != nil {
  291. return fmt.Errorf("failed to deserialize head: %v", err)
  292. }
  293. h.head = nh
  294. h.bits = binary.BigEndian.Uint64(ba[0:8])
  295. h.unselected = binary.BigEndian.Uint64(ba[8:16])
  296. return nil
  297. }
  298. // Bits returns the length of the bit sequence
  299. func (h *Bitmap) Bits() uint64 {
  300. return h.bits
  301. }
  302. // Unselected returns the number of bits which are not selected
  303. func (h *Bitmap) Unselected() uint64 {
  304. return h.unselected
  305. }
  306. func (h *Bitmap) String() string {
  307. return fmt.Sprintf("Bits: %d, Unselected: %d, Sequence: %s Curr:%d",
  308. h.bits, h.unselected, h.head.toString(), h.curr)
  309. }
  310. // MarshalJSON encodes h into a JSON message
  311. func (h *Bitmap) MarshalJSON() ([]byte, error) {
  312. b, err := h.MarshalBinary()
  313. if err != nil {
  314. return nil, err
  315. }
  316. return json.Marshal(b)
  317. }
  318. // UnmarshalJSON decodes JSON message into h
  319. func (h *Bitmap) UnmarshalJSON(data []byte) error {
  320. var b []byte
  321. if err := json.Unmarshal(data, &b); err != nil {
  322. return err
  323. }
  324. return h.UnmarshalBinary(b)
  325. }
  326. // getFirstAvailable looks for the first unset bit in passed mask starting from start
  327. func getFirstAvailable(head *sequence, start uint64) (uint64, uint64, error) {
  328. // Find sequence which contains the start bit
  329. byteStart, bitStart := ordinalToPos(start)
  330. current, _, precBlocks, inBlockBytePos := findSequence(head, byteStart)
  331. // Derive the this sequence offsets
  332. byteOffset := byteStart - inBlockBytePos
  333. bitOffset := inBlockBytePos*8 + bitStart
  334. for current != nil {
  335. if current.block != blockMAX {
  336. // If the current block is not full, check if there is any bit
  337. // from the current bit in the current block. If not, before proceeding to the
  338. // next block node, make sure we check for available bit in the next
  339. // instance of the same block. Due to RLE same block signature will be
  340. // compressed.
  341. retry:
  342. bytePos, bitPos, err := current.getAvailableBit(bitOffset)
  343. if err != nil && precBlocks == current.count-1 {
  344. // This is the last instance in the same block node,
  345. // so move to the next block.
  346. goto next
  347. }
  348. if err != nil {
  349. // There are some more instances of the same block, so add the offset
  350. // and be optimistic that you will find the available bit in the next
  351. // instance of the same block.
  352. bitOffset = 0
  353. byteOffset += blockBytes
  354. precBlocks++
  355. goto retry
  356. }
  357. return byteOffset + bytePos, bitPos, err
  358. }
  359. // Moving to next block: Reset bit offset.
  360. next:
  361. bitOffset = 0
  362. byteOffset += (current.count * blockBytes) - (precBlocks * blockBytes)
  363. precBlocks = 0
  364. current = current.next
  365. }
  366. return invalidPos, invalidPos, ErrNoBitAvailable
  367. }
  368. // getAvailableFromCurrent will look for available ordinal from the current ordinal.
  369. // If none found then it will loop back to the start to check of the available bit.
  370. // This can be further optimized to check from start till curr in case of a rollover
  371. func getAvailableFromCurrent(head *sequence, start, curr, end uint64) (uint64, uint64, error) {
  372. var bytePos, bitPos uint64
  373. var err error
  374. if curr != 0 && curr > start {
  375. bytePos, bitPos, err = getFirstAvailable(head, curr)
  376. ret := posToOrdinal(bytePos, bitPos)
  377. if end < ret || err != nil {
  378. goto begin
  379. }
  380. return bytePos, bitPos, nil
  381. }
  382. begin:
  383. bytePos, bitPos, err = getFirstAvailable(head, start)
  384. ret := posToOrdinal(bytePos, bitPos)
  385. if end < ret || err != nil {
  386. return invalidPos, invalidPos, ErrNoBitAvailable
  387. }
  388. return bytePos, bitPos, nil
  389. }
  390. // checkIfAvailable checks if the bit correspondent to the specified ordinal is unset
  391. // If the ordinal is beyond the sequence limits, a negative response is returned
  392. func checkIfAvailable(head *sequence, ordinal uint64) (uint64, uint64, error) {
  393. bytePos, bitPos := ordinalToPos(ordinal)
  394. // Find the sequence containing this byte
  395. current, _, _, inBlockBytePos := findSequence(head, bytePos)
  396. if current != nil {
  397. // Check whether the bit corresponding to the ordinal address is unset
  398. bitSel := blockFirstBit >> (inBlockBytePos*8 + bitPos)
  399. if current.block&bitSel == 0 {
  400. return bytePos, bitPos, nil
  401. }
  402. }
  403. return invalidPos, invalidPos, ErrBitAllocated
  404. }
  405. // Given the byte position and the sequences list head, return the pointer to the
  406. // sequence containing the byte (current), the pointer to the previous sequence,
  407. // the number of blocks preceding the block containing the byte inside the current sequence.
  408. // If bytePos is outside of the list, function will return (nil, nil, 0, invalidPos)
  409. func findSequence(head *sequence, bytePos uint64) (*sequence, *sequence, uint64, uint64) {
  410. // Find the sequence containing this byte
  411. previous := head
  412. current := head
  413. n := bytePos
  414. for current.next != nil && n >= (current.count*blockBytes) { // Nil check for less than 32 addresses masks
  415. n -= (current.count * blockBytes)
  416. previous = current
  417. current = current.next
  418. }
  419. // If byte is outside of the list, let caller know
  420. if n >= (current.count * blockBytes) {
  421. return nil, nil, 0, invalidPos
  422. }
  423. // Find the byte position inside the block and the number of blocks
  424. // preceding the block containing the byte inside this sequence
  425. precBlocks := n / blockBytes
  426. inBlockBytePos := bytePos % blockBytes
  427. return current, previous, precBlocks, inBlockBytePos
  428. }
  429. // PushReservation pushes the bit reservation inside the bitmask.
  430. // Given byte and bit positions, identify the sequence (current) which holds the block containing the affected bit.
  431. // Create a new block with the modified bit according to the operation (allocate/release).
  432. // Create a new sequence containing the new block and insert it in the proper position.
  433. // Remove current sequence if empty.
  434. // Check if new sequence can be merged with neighbour (previous/next) sequences.
  435. //
  436. // Identify "current" sequence containing block:
  437. //
  438. // [prev seq] [current seq] [next seq]
  439. //
  440. // Based on block position, resulting list of sequences can be any of three forms:
  441. //
  442. // block position Resulting list of sequences
  443. //
  444. // A) block is first in current: [prev seq] [new] [modified current seq] [next seq]
  445. // B) block is last in current: [prev seq] [modified current seq] [new] [next seq]
  446. // C) block is in the middle of current: [prev seq] [curr pre] [new] [curr post] [next seq]
  447. func pushReservation(bytePos, bitPos uint64, head *sequence, release bool) *sequence {
  448. // Store list's head
  449. newHead := head
  450. // Find the sequence containing this byte
  451. current, previous, precBlocks, inBlockBytePos := findSequence(head, bytePos)
  452. if current == nil {
  453. return newHead
  454. }
  455. // Construct updated block
  456. bitSel := blockFirstBit >> (inBlockBytePos*8 + bitPos)
  457. newBlock := current.block
  458. if release {
  459. newBlock &^= bitSel
  460. } else {
  461. newBlock |= bitSel
  462. }
  463. // Quit if it was a redundant request
  464. if current.block == newBlock {
  465. return newHead
  466. }
  467. // Current sequence inevitably looses one block, upadate count
  468. current.count--
  469. // Create new sequence
  470. newSequence := &sequence{block: newBlock, count: 1}
  471. // Insert the new sequence in the list based on block position
  472. if precBlocks == 0 { // First in sequence (A)
  473. newSequence.next = current
  474. if current == head {
  475. newHead = newSequence
  476. previous = newHead
  477. } else {
  478. previous.next = newSequence
  479. }
  480. removeCurrentIfEmpty(&newHead, newSequence, current)
  481. mergeSequences(previous)
  482. } else if precBlocks == current.count { // Last in sequence (B)
  483. newSequence.next = current.next
  484. current.next = newSequence
  485. mergeSequences(current)
  486. } else { // In between the sequence (C)
  487. currPre := &sequence{block: current.block, count: precBlocks, next: newSequence}
  488. currPost := current
  489. currPost.count -= precBlocks
  490. newSequence.next = currPost
  491. if currPost == head {
  492. newHead = currPre
  493. } else {
  494. previous.next = currPre
  495. }
  496. // No merging or empty current possible here
  497. }
  498. return newHead
  499. }
  500. // Removes the current sequence from the list if empty, adjusting the head pointer if needed
  501. func removeCurrentIfEmpty(head **sequence, previous, current *sequence) {
  502. if current.count == 0 {
  503. if current == *head {
  504. *head = current.next
  505. } else {
  506. previous.next = current.next
  507. }
  508. }
  509. }
  510. // Given a pointer to a sequence, it checks if it can be merged with any following sequences
  511. // It stops when no more merging is possible.
  512. // TODO: Optimization: only attempt merge from start to end sequence, no need to scan till the end of the list
  513. func mergeSequences(seq *sequence) {
  514. if seq != nil {
  515. // Merge all what possible from seq
  516. for seq.next != nil && seq.block == seq.next.block {
  517. seq.count += seq.next.count
  518. seq.next = seq.next.next
  519. }
  520. // Move to next
  521. mergeSequences(seq.next)
  522. }
  523. }
  524. func getNumBlocks(numBits uint64) uint64 {
  525. numBlocks := numBits / uint64(blockLen)
  526. if numBits%uint64(blockLen) != 0 {
  527. numBlocks++
  528. }
  529. return numBlocks
  530. }
  531. func ordinalToPos(ordinal uint64) (uint64, uint64) {
  532. return ordinal / 8, ordinal % 8
  533. }
  534. func posToOrdinal(bytePos, bitPos uint64) uint64 {
  535. return bytePos*8 + bitPos
  536. }