sequence.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585
  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 of ordinals in the interval [0, n).
  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. b := make([]byte, 12)
  130. for p != nil {
  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. // set/reset the bit
  209. func (h *Bitmap) set(ordinal, start, end uint64, any bool, release bool, serial bool) (uint64, error) {
  210. var (
  211. bitPos uint64
  212. bytePos uint64
  213. ret uint64
  214. err error
  215. )
  216. curr := uint64(0)
  217. if serial {
  218. curr = h.curr
  219. }
  220. // Get position if available
  221. if release {
  222. bytePos, bitPos = ordinalToPos(ordinal)
  223. } else {
  224. if any {
  225. bytePos, bitPos, err = getAvailableFromCurrent(h.head, start, curr, end)
  226. ret = posToOrdinal(bytePos, bitPos)
  227. if err == nil {
  228. h.curr = ret + 1
  229. }
  230. } else {
  231. bytePos, bitPos, err = checkIfAvailable(h.head, ordinal)
  232. ret = ordinal
  233. }
  234. }
  235. if err != nil {
  236. return ret, err
  237. }
  238. h.head = pushReservation(bytePos, bitPos, h.head, release)
  239. if release {
  240. h.unselected++
  241. } else {
  242. h.unselected--
  243. }
  244. return ret, nil
  245. }
  246. // checks is needed because to cover the case where the number of bits is not a multiple of blockLen
  247. func (h *Bitmap) validateOrdinal(ordinal uint64) error {
  248. if ordinal >= h.bits {
  249. return errors.New("bit does not belong to the sequence")
  250. }
  251. return nil
  252. }
  253. // MarshalBinary encodes h into a binary representation.
  254. func (h *Bitmap) MarshalBinary() ([]byte, error) {
  255. ba := make([]byte, 16)
  256. binary.BigEndian.PutUint64(ba[0:], h.bits)
  257. binary.BigEndian.PutUint64(ba[8:], h.unselected)
  258. bm, err := h.head.toByteArray()
  259. if err != nil {
  260. return nil, fmt.Errorf("failed to serialize head: %v", err)
  261. }
  262. ba = append(ba, bm...)
  263. return ba, nil
  264. }
  265. // UnmarshalBinary decodes a binary representation of a Bitmap value which was
  266. // generated using [Bitmap.MarshalBinary].
  267. //
  268. // The scan position for serial [Bitmap.SetAny] and [Bitmap.SetAnyInRange]
  269. // operations is neither unmarshaled nor reset.
  270. func (h *Bitmap) UnmarshalBinary(ba []byte) error {
  271. if ba == nil {
  272. return errors.New("nil byte array")
  273. }
  274. nh := &sequence{}
  275. err := nh.fromByteArray(ba[16:])
  276. if err != nil {
  277. return fmt.Errorf("failed to deserialize head: %v", err)
  278. }
  279. h.head = nh
  280. h.bits = binary.BigEndian.Uint64(ba[0:8])
  281. h.unselected = binary.BigEndian.Uint64(ba[8:16])
  282. return nil
  283. }
  284. // Bits returns the length of the bit sequence
  285. func (h *Bitmap) Bits() uint64 {
  286. return h.bits
  287. }
  288. // Unselected returns the number of bits which are not selected
  289. func (h *Bitmap) Unselected() uint64 {
  290. return h.unselected
  291. }
  292. func (h *Bitmap) String() string {
  293. return fmt.Sprintf("Bits: %d, Unselected: %d, Sequence: %s Curr:%d",
  294. h.bits, h.unselected, h.head.toString(), h.curr)
  295. }
  296. // MarshalJSON encodes h into a JSON message
  297. func (h *Bitmap) MarshalJSON() ([]byte, error) {
  298. b, err := h.MarshalBinary()
  299. if err != nil {
  300. return nil, err
  301. }
  302. return json.Marshal(b)
  303. }
  304. // UnmarshalJSON decodes JSON message into h
  305. func (h *Bitmap) UnmarshalJSON(data []byte) error {
  306. var b []byte
  307. if err := json.Unmarshal(data, &b); err != nil {
  308. return err
  309. }
  310. return h.UnmarshalBinary(b)
  311. }
  312. // getFirstAvailable looks for the first unset bit in passed mask starting from start
  313. func getFirstAvailable(head *sequence, start uint64) (uint64, uint64, error) {
  314. // Find sequence which contains the start bit
  315. byteStart, bitStart := ordinalToPos(start)
  316. current, _, precBlocks, inBlockBytePos := findSequence(head, byteStart)
  317. // Derive the this sequence offsets
  318. byteOffset := byteStart - inBlockBytePos
  319. bitOffset := inBlockBytePos*8 + bitStart
  320. for current != nil {
  321. if current.block != blockMAX {
  322. // If the current block is not full, check if there is any bit
  323. // from the current bit in the current block. If not, before proceeding to the
  324. // next block node, make sure we check for available bit in the next
  325. // instance of the same block. Due to RLE same block signature will be
  326. // compressed.
  327. retry:
  328. bytePos, bitPos, err := current.getAvailableBit(bitOffset)
  329. if err != nil && precBlocks == current.count-1 {
  330. // This is the last instance in the same block node,
  331. // so move to the next block.
  332. goto next
  333. }
  334. if err != nil {
  335. // There are some more instances of the same block, so add the offset
  336. // and be optimistic that you will find the available bit in the next
  337. // instance of the same block.
  338. bitOffset = 0
  339. byteOffset += blockBytes
  340. precBlocks++
  341. goto retry
  342. }
  343. return byteOffset + bytePos, bitPos, err
  344. }
  345. // Moving to next block: Reset bit offset.
  346. next:
  347. bitOffset = 0
  348. byteOffset += (current.count * blockBytes) - (precBlocks * blockBytes)
  349. precBlocks = 0
  350. current = current.next
  351. }
  352. return invalidPos, invalidPos, ErrNoBitAvailable
  353. }
  354. // getAvailableFromCurrent will look for available ordinal from the current ordinal.
  355. // If none found then it will loop back to the start to check of the available bit.
  356. // This can be further optimized to check from start till curr in case of a rollover
  357. func getAvailableFromCurrent(head *sequence, start, curr, end uint64) (uint64, uint64, error) {
  358. var bytePos, bitPos uint64
  359. var err error
  360. if curr != 0 && curr > start {
  361. bytePos, bitPos, err = getFirstAvailable(head, curr)
  362. ret := posToOrdinal(bytePos, bitPos)
  363. if end < ret || err != nil {
  364. goto begin
  365. }
  366. return bytePos, bitPos, nil
  367. }
  368. begin:
  369. bytePos, bitPos, err = getFirstAvailable(head, start)
  370. ret := posToOrdinal(bytePos, bitPos)
  371. if end < ret || err != nil {
  372. return invalidPos, invalidPos, ErrNoBitAvailable
  373. }
  374. return bytePos, bitPos, nil
  375. }
  376. // checkIfAvailable checks if the bit correspondent to the specified ordinal is unset
  377. // If the ordinal is beyond the sequence limits, a negative response is returned
  378. func checkIfAvailable(head *sequence, ordinal uint64) (uint64, uint64, error) {
  379. bytePos, bitPos := ordinalToPos(ordinal)
  380. // Find the sequence containing this byte
  381. current, _, _, inBlockBytePos := findSequence(head, bytePos)
  382. if current != nil {
  383. // Check whether the bit corresponding to the ordinal address is unset
  384. bitSel := blockFirstBit >> (inBlockBytePos*8 + bitPos)
  385. if current.block&bitSel == 0 {
  386. return bytePos, bitPos, nil
  387. }
  388. }
  389. return invalidPos, invalidPos, ErrBitAllocated
  390. }
  391. // Given the byte position and the sequences list head, return the pointer to the
  392. // sequence containing the byte (current), the pointer to the previous sequence,
  393. // the number of blocks preceding the block containing the byte inside the current sequence.
  394. // If bytePos is outside of the list, function will return (nil, nil, 0, invalidPos)
  395. func findSequence(head *sequence, bytePos uint64) (*sequence, *sequence, uint64, uint64) {
  396. // Find the sequence containing this byte
  397. previous := head
  398. current := head
  399. n := bytePos
  400. for current.next != nil && n >= (current.count*blockBytes) { // Nil check for less than 32 addresses masks
  401. n -= (current.count * blockBytes)
  402. previous = current
  403. current = current.next
  404. }
  405. // If byte is outside of the list, let caller know
  406. if n >= (current.count * blockBytes) {
  407. return nil, nil, 0, invalidPos
  408. }
  409. // Find the byte position inside the block and the number of blocks
  410. // preceding the block containing the byte inside this sequence
  411. precBlocks := n / blockBytes
  412. inBlockBytePos := bytePos % blockBytes
  413. return current, previous, precBlocks, inBlockBytePos
  414. }
  415. // PushReservation pushes the bit reservation inside the bitmask.
  416. // Given byte and bit positions, identify the sequence (current) which holds the block containing the affected bit.
  417. // Create a new block with the modified bit according to the operation (allocate/release).
  418. // Create a new sequence containing the new block and insert it in the proper position.
  419. // Remove current sequence if empty.
  420. // Check if new sequence can be merged with neighbour (previous/next) sequences.
  421. //
  422. // Identify "current" sequence containing block:
  423. //
  424. // [prev seq] [current seq] [next seq]
  425. //
  426. // Based on block position, resulting list of sequences can be any of three forms:
  427. //
  428. // block position Resulting list of sequences
  429. //
  430. // A) block is first in current: [prev seq] [new] [modified current seq] [next seq]
  431. // B) block is last in current: [prev seq] [modified current seq] [new] [next seq]
  432. // C) block is in the middle of current: [prev seq] [curr pre] [new] [curr post] [next seq]
  433. func pushReservation(bytePos, bitPos uint64, head *sequence, release bool) *sequence {
  434. // Store list's head
  435. newHead := head
  436. // Find the sequence containing this byte
  437. current, previous, precBlocks, inBlockBytePos := findSequence(head, bytePos)
  438. if current == nil {
  439. return newHead
  440. }
  441. // Construct updated block
  442. bitSel := blockFirstBit >> (inBlockBytePos*8 + bitPos)
  443. newBlock := current.block
  444. if release {
  445. newBlock &^= bitSel
  446. } else {
  447. newBlock |= bitSel
  448. }
  449. // Quit if it was a redundant request
  450. if current.block == newBlock {
  451. return newHead
  452. }
  453. // Current sequence inevitably looses one block, upadate count
  454. current.count--
  455. // Create new sequence
  456. newSequence := &sequence{block: newBlock, count: 1}
  457. // Insert the new sequence in the list based on block position
  458. if precBlocks == 0 { // First in sequence (A)
  459. newSequence.next = current
  460. if current == head {
  461. newHead = newSequence
  462. previous = newHead
  463. } else {
  464. previous.next = newSequence
  465. }
  466. removeCurrentIfEmpty(&newHead, newSequence, current)
  467. mergeSequences(previous)
  468. } else if precBlocks == current.count { // Last in sequence (B)
  469. newSequence.next = current.next
  470. current.next = newSequence
  471. mergeSequences(current)
  472. } else { // In between the sequence (C)
  473. currPre := &sequence{block: current.block, count: precBlocks, next: newSequence}
  474. currPost := current
  475. currPost.count -= precBlocks
  476. newSequence.next = currPost
  477. if currPost == head {
  478. newHead = currPre
  479. } else {
  480. previous.next = currPre
  481. }
  482. // No merging or empty current possible here
  483. }
  484. return newHead
  485. }
  486. // Removes the current sequence from the list if empty, adjusting the head pointer if needed
  487. func removeCurrentIfEmpty(head **sequence, previous, current *sequence) {
  488. if current.count == 0 {
  489. if current == *head {
  490. *head = current.next
  491. } else {
  492. previous.next = current.next
  493. }
  494. }
  495. }
  496. // Given a pointer to a sequence, it checks if it can be merged with any following sequences
  497. // It stops when no more merging is possible.
  498. // TODO: Optimization: only attempt merge from start to end sequence, no need to scan till the end of the list
  499. func mergeSequences(seq *sequence) {
  500. if seq != nil {
  501. // Merge all what possible from seq
  502. for seq.next != nil && seq.block == seq.next.block {
  503. seq.count += seq.next.count
  504. seq.next = seq.next.next
  505. }
  506. // Move to next
  507. mergeSequences(seq.next)
  508. }
  509. }
  510. func getNumBlocks(numBits uint64) uint64 {
  511. numBlocks := numBits / uint64(blockLen)
  512. if numBits%uint64(blockLen) != 0 {
  513. numBlocks++
  514. }
  515. return numBlocks
  516. }
  517. func ordinalToPos(ordinal uint64) (uint64, uint64) {
  518. return ordinal / 8, ordinal % 8
  519. }
  520. func posToOrdinal(bytePos, bitPos uint64) uint64 {
  521. return bytePos*8 + bitPos
  522. }