github.com/docker/engine@v22.0.0-20211208180946-d456264580cf+incompatible/libnetwork/bitseq/sequence.go (about)

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