sequence.go 20 KB

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