sequence.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731
  1. // Package bitseq provides a structure and utilities for representing long bitmask
  2. // as sequence of run-length encoded blocks. It operates directly on the encoded
  3. // representation, it does not decode/encode.
  4. package bitseq
  5. import (
  6. "encoding/binary"
  7. "encoding/json"
  8. "errors"
  9. "fmt"
  10. "sync"
  11. "github.com/docker/docker/libnetwork/datastore"
  12. "github.com/docker/docker/libnetwork/types"
  13. "github.com/sirupsen/logrus"
  14. )
  15. // block sequence constants
  16. // If needed we can think of making these configurable
  17. const (
  18. blockLen = uint32(32)
  19. blockBytes = uint64(blockLen / 8)
  20. blockMAX = uint32(1<<blockLen - 1)
  21. blockFirstBit = uint32(1) << (blockLen - 1)
  22. invalidPos = uint64(0xFFFFFFFFFFFFFFFF)
  23. )
  24. var (
  25. // ErrNoBitAvailable is returned when no more bits are available to set
  26. ErrNoBitAvailable = errors.New("no bit available")
  27. // ErrBitAllocated is returned when the specific bit requested is already set
  28. ErrBitAllocated = errors.New("requested bit is already allocated")
  29. )
  30. // Handle contains the sequence representing the bitmask and its identifier
  31. type Handle struct {
  32. bits uint64
  33. unselected uint64
  34. head *sequence
  35. app string
  36. id string
  37. dbIndex uint64
  38. dbExists bool
  39. curr uint64
  40. store datastore.DataStore
  41. sync.Mutex
  42. }
  43. // NewHandle returns a thread-safe instance of the bitmask handler
  44. func NewHandle(app string, ds datastore.DataStore, id string, numElements uint64) (*Handle, error) {
  45. h := &Handle{
  46. app: app,
  47. id: id,
  48. store: ds,
  49. bits: numElements,
  50. unselected: numElements,
  51. head: &sequence{
  52. block: 0x0,
  53. count: getNumBlocks(numElements),
  54. },
  55. }
  56. if h.store == nil {
  57. return h, nil
  58. }
  59. // Get the initial status from the ds if present.
  60. if err := h.store.GetObject(datastore.Key(h.Key()...), h); err != nil && err != datastore.ErrKeyNotFound {
  61. return nil, err
  62. }
  63. // If the handle is not in store, write it.
  64. if !h.Exists() {
  65. if err := h.writeToStore(); err != nil {
  66. return nil, fmt.Errorf("failed to write bitsequence to store: %v", err)
  67. }
  68. }
  69. return h, nil
  70. }
  71. // sequence represents a recurring sequence of 32 bits long bitmasks
  72. type sequence struct {
  73. block uint32 // block is a symbol representing 4 byte long allocation bitmask
  74. count uint64 // number of consecutive blocks (symbols)
  75. next *sequence // next sequence
  76. }
  77. // String returns a string representation of the block sequence starting from this block
  78. func (s *sequence) toString() string {
  79. var nextBlock string
  80. if s.next == nil {
  81. nextBlock = "end"
  82. } else {
  83. nextBlock = s.next.toString()
  84. }
  85. return fmt.Sprintf("(0x%x, %d)->%s", s.block, s.count, nextBlock)
  86. }
  87. // GetAvailableBit returns the position of the first unset bit in the bitmask represented by this sequence
  88. func (s *sequence) getAvailableBit(from uint64) (uint64, uint64, error) {
  89. if s.block == blockMAX || s.count == 0 {
  90. return invalidPos, invalidPos, ErrNoBitAvailable
  91. }
  92. bits := from
  93. bitSel := blockFirstBit >> from
  94. for bitSel > 0 && s.block&bitSel != 0 {
  95. bitSel >>= 1
  96. bits++
  97. }
  98. // Check if the loop exited because it could not
  99. // find any available bit int block starting from
  100. // "from". Return invalid pos in that case.
  101. if bitSel == 0 {
  102. return invalidPos, invalidPos, ErrNoBitAvailable
  103. }
  104. return bits / 8, bits % 8, nil
  105. }
  106. // GetCopy returns a copy of the linked list rooted at this node
  107. func (s *sequence) getCopy() *sequence {
  108. n := &sequence{block: s.block, count: s.count}
  109. pn := n
  110. ps := s.next
  111. for ps != nil {
  112. pn.next = &sequence{block: ps.block, count: ps.count}
  113. pn = pn.next
  114. ps = ps.next
  115. }
  116. return n
  117. }
  118. // Equal checks if this sequence is equal to the passed one
  119. func (s *sequence) equal(o *sequence) bool {
  120. this := s
  121. other := o
  122. for this != nil {
  123. if other == nil {
  124. return false
  125. }
  126. if this.block != other.block || this.count != other.count {
  127. return false
  128. }
  129. this = this.next
  130. other = other.next
  131. }
  132. return other == nil
  133. }
  134. // ToByteArray converts the sequence into a byte array
  135. func (s *sequence) toByteArray() ([]byte, error) {
  136. var bb []byte
  137. p := s
  138. for p != nil {
  139. b := make([]byte, 12)
  140. binary.BigEndian.PutUint32(b[0:], p.block)
  141. binary.BigEndian.PutUint64(b[4:], p.count)
  142. bb = append(bb, b...)
  143. p = p.next
  144. }
  145. return bb, nil
  146. }
  147. // fromByteArray construct the sequence from the byte array
  148. func (s *sequence) fromByteArray(data []byte) error {
  149. l := len(data)
  150. if l%12 != 0 {
  151. return fmt.Errorf("cannot deserialize byte sequence of length %d (%v)", l, data)
  152. }
  153. p := s
  154. i := 0
  155. for {
  156. p.block = binary.BigEndian.Uint32(data[i : i+4])
  157. p.count = binary.BigEndian.Uint64(data[i+4 : i+12])
  158. i += 12
  159. if i == l {
  160. break
  161. }
  162. p.next = &sequence{}
  163. p = p.next
  164. }
  165. return nil
  166. }
  167. func (h *Handle) getCopy() *Handle {
  168. return &Handle{
  169. bits: h.bits,
  170. unselected: h.unselected,
  171. head: h.head.getCopy(),
  172. app: h.app,
  173. id: h.id,
  174. dbIndex: h.dbIndex,
  175. dbExists: h.dbExists,
  176. store: h.store,
  177. curr: h.curr,
  178. }
  179. }
  180. // SetAnyInRange atomically sets the first unset bit in the specified range in the sequence and returns the corresponding ordinal
  181. func (h *Handle) SetAnyInRange(start, end uint64, serial bool) (uint64, error) {
  182. if end < start || end >= h.bits {
  183. return invalidPos, fmt.Errorf("invalid bit range [%d, %d]", start, end)
  184. }
  185. if h.Unselected() == 0 {
  186. return invalidPos, ErrNoBitAvailable
  187. }
  188. return h.set(0, start, end, true, false, serial)
  189. }
  190. // SetAny atomically sets the first unset bit in the sequence and returns the corresponding ordinal
  191. func (h *Handle) SetAny(serial bool) (uint64, error) {
  192. if h.Unselected() == 0 {
  193. return invalidPos, ErrNoBitAvailable
  194. }
  195. return h.set(0, 0, h.bits-1, true, false, serial)
  196. }
  197. // Set atomically sets the corresponding bit in the sequence
  198. func (h *Handle) Set(ordinal uint64) error {
  199. if err := h.validateOrdinal(ordinal); err != nil {
  200. return err
  201. }
  202. _, err := h.set(ordinal, 0, 0, false, false, false)
  203. return err
  204. }
  205. // Unset atomically unsets the corresponding bit in the sequence
  206. func (h *Handle) Unset(ordinal uint64) error {
  207. if err := h.validateOrdinal(ordinal); err != nil {
  208. return err
  209. }
  210. _, err := h.set(ordinal, 0, 0, false, true, false)
  211. return err
  212. }
  213. // IsSet atomically checks if the ordinal bit is set. In case ordinal
  214. // is outside of the bit sequence limits, false is returned.
  215. func (h *Handle) IsSet(ordinal uint64) bool {
  216. if err := h.validateOrdinal(ordinal); err != nil {
  217. return false
  218. }
  219. h.Lock()
  220. _, _, err := checkIfAvailable(h.head, ordinal)
  221. h.Unlock()
  222. return err != nil
  223. }
  224. func (h *Handle) runConsistencyCheck() bool {
  225. corrupted := false
  226. for p, c := h.head, h.head.next; c != nil; c = c.next {
  227. if c.count == 0 {
  228. corrupted = true
  229. p.next = c.next
  230. continue // keep same p
  231. }
  232. p = c
  233. }
  234. return corrupted
  235. }
  236. // CheckConsistency checks if the bit sequence is in an inconsistent state and attempts to fix it.
  237. // It looks for a corruption signature that may happen in docker 1.9.0 and 1.9.1.
  238. func (h *Handle) CheckConsistency() error {
  239. for {
  240. h.Lock()
  241. store := h.store
  242. h.Unlock()
  243. if store != nil {
  244. if err := store.GetObject(datastore.Key(h.Key()...), h); err != nil && err != datastore.ErrKeyNotFound {
  245. return err
  246. }
  247. }
  248. h.Lock()
  249. nh := h.getCopy()
  250. h.Unlock()
  251. if !nh.runConsistencyCheck() {
  252. return nil
  253. }
  254. if err := nh.writeToStore(); err != nil {
  255. if _, ok := err.(types.RetryError); !ok {
  256. return fmt.Errorf("internal failure while fixing inconsistent bitsequence: %v", err)
  257. }
  258. continue
  259. }
  260. logrus.Infof("Fixed inconsistent bit sequence in datastore:\n%s\n%s", h, nh)
  261. h.Lock()
  262. h.head = nh.head
  263. h.Unlock()
  264. return nil
  265. }
  266. }
  267. // set/reset the bit
  268. func (h *Handle) set(ordinal, start, end uint64, any bool, release bool, serial bool) (uint64, error) {
  269. var (
  270. bitPos uint64
  271. bytePos uint64
  272. ret uint64
  273. err error
  274. )
  275. for {
  276. var store datastore.DataStore
  277. curr := uint64(0)
  278. h.Lock()
  279. store = h.store
  280. if store != nil {
  281. h.Unlock() // The lock is acquired in the GetObject
  282. if err := store.GetObject(datastore.Key(h.Key()...), h); err != nil && err != datastore.ErrKeyNotFound {
  283. return ret, err
  284. }
  285. h.Lock() // Acquire the lock back
  286. }
  287. if serial {
  288. curr = h.curr
  289. }
  290. // Get position if available
  291. if release {
  292. bytePos, bitPos = ordinalToPos(ordinal)
  293. } else {
  294. if any {
  295. bytePos, bitPos, err = getAvailableFromCurrent(h.head, start, curr, end)
  296. ret = posToOrdinal(bytePos, bitPos)
  297. if err == nil {
  298. h.curr = ret + 1
  299. }
  300. } else {
  301. bytePos, bitPos, err = checkIfAvailable(h.head, ordinal)
  302. ret = ordinal
  303. }
  304. }
  305. if err != nil {
  306. h.Unlock()
  307. return ret, err
  308. }
  309. // Create a private copy of h and work on it
  310. nh := h.getCopy()
  311. nh.head = pushReservation(bytePos, bitPos, nh.head, release)
  312. if release {
  313. nh.unselected++
  314. } else {
  315. nh.unselected--
  316. }
  317. if h.store != nil {
  318. h.Unlock()
  319. // Attempt to write private copy to store
  320. if err := nh.writeToStore(); err != nil {
  321. if _, ok := err.(types.RetryError); !ok {
  322. return ret, fmt.Errorf("internal failure while setting the bit: %v", err)
  323. }
  324. // Retry
  325. continue
  326. }
  327. h.Lock()
  328. }
  329. // Previous atomic push was successful. Save private copy to local copy
  330. h.unselected = nh.unselected
  331. h.head = nh.head
  332. h.dbExists = nh.dbExists
  333. h.dbIndex = nh.dbIndex
  334. h.Unlock()
  335. return ret, nil
  336. }
  337. }
  338. // checks is needed because to cover the case where the number of bits is not a multiple of blockLen
  339. func (h *Handle) validateOrdinal(ordinal uint64) error {
  340. h.Lock()
  341. defer h.Unlock()
  342. if ordinal >= h.bits {
  343. return errors.New("bit does not belong to the sequence")
  344. }
  345. return nil
  346. }
  347. // Destroy removes from the datastore the data belonging to this handle
  348. func (h *Handle) Destroy() error {
  349. for {
  350. if err := h.deleteFromStore(); err != nil {
  351. if _, ok := err.(types.RetryError); !ok {
  352. return fmt.Errorf("internal failure while destroying the sequence: %v", err)
  353. }
  354. // Fetch latest
  355. if err := h.store.GetObject(datastore.Key(h.Key()...), h); err != nil {
  356. if err == datastore.ErrKeyNotFound { // already removed
  357. return nil
  358. }
  359. return fmt.Errorf("failed to fetch from store when destroying the sequence: %v", err)
  360. }
  361. continue
  362. }
  363. return nil
  364. }
  365. }
  366. // ToByteArray converts this handle's data into a byte array
  367. func (h *Handle) ToByteArray() ([]byte, error) {
  368. h.Lock()
  369. defer h.Unlock()
  370. ba := make([]byte, 16)
  371. binary.BigEndian.PutUint64(ba[0:], h.bits)
  372. binary.BigEndian.PutUint64(ba[8:], h.unselected)
  373. bm, err := h.head.toByteArray()
  374. if err != nil {
  375. return nil, fmt.Errorf("failed to serialize head: %s", err.Error())
  376. }
  377. ba = append(ba, bm...)
  378. return ba, nil
  379. }
  380. // FromByteArray reads his handle's data from a byte array
  381. func (h *Handle) FromByteArray(ba []byte) error {
  382. if ba == nil {
  383. return errors.New("nil byte array")
  384. }
  385. nh := &sequence{}
  386. err := nh.fromByteArray(ba[16:])
  387. if err != nil {
  388. return fmt.Errorf("failed to deserialize head: %s", err.Error())
  389. }
  390. h.Lock()
  391. h.head = nh
  392. h.bits = binary.BigEndian.Uint64(ba[0:8])
  393. h.unselected = binary.BigEndian.Uint64(ba[8:16])
  394. h.Unlock()
  395. return nil
  396. }
  397. // Bits returns the length of the bit sequence
  398. func (h *Handle) Bits() uint64 {
  399. return h.bits
  400. }
  401. // Unselected returns the number of bits which are not selected
  402. func (h *Handle) Unselected() uint64 {
  403. h.Lock()
  404. defer h.Unlock()
  405. return h.unselected
  406. }
  407. func (h *Handle) String() string {
  408. h.Lock()
  409. defer h.Unlock()
  410. return fmt.Sprintf("App: %s, ID: %s, DBIndex: 0x%x, Bits: %d, Unselected: %d, Sequence: %s Curr:%d",
  411. h.app, h.id, h.dbIndex, h.bits, h.unselected, h.head.toString(), h.curr)
  412. }
  413. // MarshalJSON encodes Handle into json message
  414. func (h *Handle) MarshalJSON() ([]byte, error) {
  415. m := map[string]interface{}{
  416. "id": h.id,
  417. }
  418. b, err := h.ToByteArray()
  419. if err != nil {
  420. return nil, err
  421. }
  422. m["sequence"] = b
  423. return json.Marshal(m)
  424. }
  425. // UnmarshalJSON decodes json message into Handle
  426. func (h *Handle) UnmarshalJSON(data []byte) error {
  427. var (
  428. m map[string]interface{}
  429. b []byte
  430. err error
  431. )
  432. if err = json.Unmarshal(data, &m); err != nil {
  433. return err
  434. }
  435. h.id = m["id"].(string)
  436. bi, _ := json.Marshal(m["sequence"])
  437. if err := json.Unmarshal(bi, &b); err != nil {
  438. return err
  439. }
  440. return h.FromByteArray(b)
  441. }
  442. // getFirstAvailable looks for the first unset bit in passed mask starting from start
  443. func getFirstAvailable(head *sequence, start uint64) (uint64, uint64, error) {
  444. // Find sequence which contains the start bit
  445. byteStart, bitStart := ordinalToPos(start)
  446. current, _, precBlocks, inBlockBytePos := findSequence(head, byteStart)
  447. // Derive the this sequence offsets
  448. byteOffset := byteStart - inBlockBytePos
  449. bitOffset := inBlockBytePos*8 + bitStart
  450. for current != nil {
  451. if current.block != blockMAX {
  452. // If the current block is not full, check if there is any bit
  453. // from the current bit in the current block. If not, before proceeding to the
  454. // next block node, make sure we check for available bit in the next
  455. // instance of the same block. Due to RLE same block signature will be
  456. // compressed.
  457. retry:
  458. bytePos, bitPos, err := current.getAvailableBit(bitOffset)
  459. if err != nil && precBlocks == current.count-1 {
  460. // This is the last instance in the same block node,
  461. // so move to the next block.
  462. goto next
  463. }
  464. if err != nil {
  465. // There are some more instances of the same block, so add the offset
  466. // and be optimistic that you will find the available bit in the next
  467. // instance of the same block.
  468. bitOffset = 0
  469. byteOffset += blockBytes
  470. precBlocks++
  471. goto retry
  472. }
  473. return byteOffset + bytePos, bitPos, err
  474. }
  475. // Moving to next block: Reset bit offset.
  476. next:
  477. bitOffset = 0
  478. byteOffset += (current.count * blockBytes) - (precBlocks * blockBytes)
  479. precBlocks = 0
  480. current = current.next
  481. }
  482. return invalidPos, invalidPos, ErrNoBitAvailable
  483. }
  484. // getAvailableFromCurrent will look for available ordinal from the current ordinal.
  485. // If none found then it will loop back to the start to check of the available bit.
  486. // This can be further optimized to check from start till curr in case of a rollover
  487. func getAvailableFromCurrent(head *sequence, start, curr, end uint64) (uint64, uint64, error) {
  488. var bytePos, bitPos uint64
  489. var err error
  490. if curr != 0 && curr > start {
  491. bytePos, bitPos, err = getFirstAvailable(head, curr)
  492. ret := posToOrdinal(bytePos, bitPos)
  493. if end < ret || err != nil {
  494. goto begin
  495. }
  496. return bytePos, bitPos, nil
  497. }
  498. begin:
  499. bytePos, bitPos, err = getFirstAvailable(head, start)
  500. ret := posToOrdinal(bytePos, bitPos)
  501. if end < ret || err != nil {
  502. return invalidPos, invalidPos, ErrNoBitAvailable
  503. }
  504. return bytePos, bitPos, nil
  505. }
  506. // checkIfAvailable checks if the bit correspondent to the specified ordinal is unset
  507. // If the ordinal is beyond the sequence limits, a negative response is returned
  508. func checkIfAvailable(head *sequence, ordinal uint64) (uint64, uint64, error) {
  509. bytePos, bitPos := ordinalToPos(ordinal)
  510. // Find the sequence containing this byte
  511. current, _, _, inBlockBytePos := findSequence(head, bytePos)
  512. if current != nil {
  513. // Check whether the bit corresponding to the ordinal address is unset
  514. bitSel := blockFirstBit >> (inBlockBytePos*8 + bitPos)
  515. if current.block&bitSel == 0 {
  516. return bytePos, bitPos, nil
  517. }
  518. }
  519. return invalidPos, invalidPos, ErrBitAllocated
  520. }
  521. // Given the byte position and the sequences list head, return the pointer to the
  522. // sequence containing the byte (current), the pointer to the previous sequence,
  523. // the number of blocks preceding the block containing the byte inside the current sequence.
  524. // If bytePos is outside of the list, function will return (nil, nil, 0, invalidPos)
  525. func findSequence(head *sequence, bytePos uint64) (*sequence, *sequence, uint64, uint64) {
  526. // Find the sequence containing this byte
  527. previous := head
  528. current := head
  529. n := bytePos
  530. for current.next != nil && n >= (current.count*blockBytes) { // Nil check for less than 32 addresses masks
  531. n -= (current.count * blockBytes)
  532. previous = current
  533. current = current.next
  534. }
  535. // If byte is outside of the list, let caller know
  536. if n >= (current.count * blockBytes) {
  537. return nil, nil, 0, invalidPos
  538. }
  539. // Find the byte position inside the block and the number of blocks
  540. // preceding the block containing the byte inside this sequence
  541. precBlocks := n / blockBytes
  542. inBlockBytePos := bytePos % blockBytes
  543. return current, previous, precBlocks, inBlockBytePos
  544. }
  545. // PushReservation pushes the bit reservation inside the bitmask.
  546. // Given byte and bit positions, identify the sequence (current) which holds the block containing the affected bit.
  547. // Create a new block with the modified bit according to the operation (allocate/release).
  548. // Create a new sequence containing the new block and insert it in the proper position.
  549. // Remove current sequence if empty.
  550. // Check if new sequence can be merged with neighbour (previous/next) sequences.
  551. //
  552. //
  553. // Identify "current" sequence containing block:
  554. // [prev seq] [current seq] [next seq]
  555. //
  556. // Based on block position, resulting list of sequences can be any of three forms:
  557. //
  558. // block position Resulting list of sequences
  559. // A) block is first in current: [prev seq] [new] [modified current seq] [next seq]
  560. // B) block is last in current: [prev seq] [modified current seq] [new] [next seq]
  561. // C) block is in the middle of current: [prev seq] [curr pre] [new] [curr post] [next seq]
  562. func pushReservation(bytePos, bitPos uint64, head *sequence, release bool) *sequence {
  563. // Store list's head
  564. newHead := head
  565. // Find the sequence containing this byte
  566. current, previous, precBlocks, inBlockBytePos := findSequence(head, bytePos)
  567. if current == nil {
  568. return newHead
  569. }
  570. // Construct updated block
  571. bitSel := blockFirstBit >> (inBlockBytePos*8 + bitPos)
  572. newBlock := current.block
  573. if release {
  574. newBlock &^= bitSel
  575. } else {
  576. newBlock |= bitSel
  577. }
  578. // Quit if it was a redundant request
  579. if current.block == newBlock {
  580. return newHead
  581. }
  582. // Current sequence inevitably looses one block, upadate count
  583. current.count--
  584. // Create new sequence
  585. newSequence := &sequence{block: newBlock, count: 1}
  586. // Insert the new sequence in the list based on block position
  587. if precBlocks == 0 { // First in sequence (A)
  588. newSequence.next = current
  589. if current == head {
  590. newHead = newSequence
  591. previous = newHead
  592. } else {
  593. previous.next = newSequence
  594. }
  595. removeCurrentIfEmpty(&newHead, newSequence, current)
  596. mergeSequences(previous)
  597. } else if precBlocks == current.count { // Last in sequence (B)
  598. newSequence.next = current.next
  599. current.next = newSequence
  600. mergeSequences(current)
  601. } else { // In between the sequence (C)
  602. currPre := &sequence{block: current.block, count: precBlocks, next: newSequence}
  603. currPost := current
  604. currPost.count -= precBlocks
  605. newSequence.next = currPost
  606. if currPost == head {
  607. newHead = currPre
  608. } else {
  609. previous.next = currPre
  610. }
  611. // No merging or empty current possible here
  612. }
  613. return newHead
  614. }
  615. // Removes the current sequence from the list if empty, adjusting the head pointer if needed
  616. func removeCurrentIfEmpty(head **sequence, previous, current *sequence) {
  617. if current.count == 0 {
  618. if current == *head {
  619. *head = current.next
  620. } else {
  621. previous.next = current.next
  622. }
  623. }
  624. }
  625. // Given a pointer to a sequence, it checks if it can be merged with any following sequences
  626. // It stops when no more merging is possible.
  627. // TODO: Optimization: only attempt merge from start to end sequence, no need to scan till the end of the list
  628. func mergeSequences(seq *sequence) {
  629. if seq != nil {
  630. // Merge all what possible from seq
  631. for seq.next != nil && seq.block == seq.next.block {
  632. seq.count += seq.next.count
  633. seq.next = seq.next.next
  634. }
  635. // Move to next
  636. mergeSequences(seq.next)
  637. }
  638. }
  639. func getNumBlocks(numBits uint64) uint64 {
  640. numBlocks := numBits / uint64(blockLen)
  641. if numBits%uint64(blockLen) != 0 {
  642. numBlocks++
  643. }
  644. return numBlocks
  645. }
  646. func ordinalToPos(ordinal uint64) (uint64, uint64) {
  647. return ordinal / 8, ordinal % 8
  648. }
  649. func posToOrdinal(bytePos, bitPos uint64) uint64 {
  650. return bytePos*8 + bitPos
  651. }