Browse code

Merge pull request #44864 from corhere/libnet/split-bitseq

libnetwork: split package bitseq

Brian Goff authored on 2023/01/27 04:44:45
Showing 5 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,600 @@
0
+// Package bitmap provides a datatype for long vectors of bits.
1
+package bitmap
2
+
3
+import (
4
+	"encoding/binary"
5
+	"encoding/json"
6
+	"errors"
7
+	"fmt"
8
+)
9
+
10
+// block sequence constants
11
+// If needed we can think of making these configurable
12
+const (
13
+	blockLen      = uint32(32)
14
+	blockBytes    = uint64(blockLen / 8)
15
+	blockMAX      = uint32(1<<blockLen - 1)
16
+	blockFirstBit = uint32(1) << (blockLen - 1)
17
+	invalidPos    = uint64(0xFFFFFFFFFFFFFFFF)
18
+)
19
+
20
+var (
21
+	// ErrNoBitAvailable is returned when no more bits are available to set
22
+	ErrNoBitAvailable = errors.New("no bit available")
23
+	// ErrBitAllocated is returned when the specific bit requested is already set
24
+	ErrBitAllocated = errors.New("requested bit is already allocated")
25
+)
26
+
27
+// https://github.com/golang/go/issues/8005#issuecomment-190753527
28
+type noCopy struct{}
29
+
30
+func (noCopy) Lock() {}
31
+
32
+// Bitmap is a fixed-length bit vector. It is not safe for concurrent use.
33
+//
34
+// The data is stored as a list of run-length encoded blocks. It operates
35
+// directly on the encoded representation, without decompressing.
36
+type Bitmap struct {
37
+	bits       uint64
38
+	unselected uint64
39
+	head       *sequence
40
+	curr       uint64
41
+
42
+	// Shallow copies would share the same head pointer but a copy of the
43
+	// unselected count. Mutating the sequence through one would change the
44
+	// bits for all copies but only update that one copy's unselected count,
45
+	// which would result in subtle bugs.
46
+	noCopy noCopy
47
+}
48
+
49
+// NewHandle returns a new Bitmap n bits long.
50
+func New(n uint64) *Bitmap {
51
+	return &Bitmap{
52
+		bits:       n,
53
+		unselected: n,
54
+		head: &sequence{
55
+			block: 0x0,
56
+			count: getNumBlocks(n),
57
+		},
58
+	}
59
+}
60
+
61
+// Copy returns a deep copy of b.
62
+func Copy(b *Bitmap) *Bitmap {
63
+	return &Bitmap{
64
+		bits:       b.bits,
65
+		unselected: b.unselected,
66
+		head:       b.head.getCopy(),
67
+		curr:       b.curr,
68
+	}
69
+}
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
+
78
+// String returns a string representation of the block sequence starting from this block
79
+func (s *sequence) toString() string {
80
+	var nextBlock string
81
+	if s.next == nil {
82
+		nextBlock = "end"
83
+	} else {
84
+		nextBlock = s.next.toString()
85
+	}
86
+	return fmt.Sprintf("(0x%x, %d)->%s", s.block, s.count, nextBlock)
87
+}
88
+
89
+// GetAvailableBit returns the position of the first unset bit in the bitmask represented by this sequence
90
+func (s *sequence) getAvailableBit(from uint64) (uint64, uint64, error) {
91
+	if s.block == blockMAX || s.count == 0 {
92
+		return invalidPos, invalidPos, ErrNoBitAvailable
93
+	}
94
+	bits := from
95
+	bitSel := blockFirstBit >> from
96
+	for bitSel > 0 && s.block&bitSel != 0 {
97
+		bitSel >>= 1
98
+		bits++
99
+	}
100
+	// Check if the loop exited because it could not
101
+	// find any available bit int block  starting from
102
+	// "from". Return invalid pos in that case.
103
+	if bitSel == 0 {
104
+		return invalidPos, invalidPos, ErrNoBitAvailable
105
+	}
106
+	return bits / 8, bits % 8, nil
107
+}
108
+
109
+// GetCopy returns a copy of the linked list rooted at this node
110
+func (s *sequence) getCopy() *sequence {
111
+	n := &sequence{block: s.block, count: s.count}
112
+	pn := n
113
+	ps := s.next
114
+	for ps != nil {
115
+		pn.next = &sequence{block: ps.block, count: ps.count}
116
+		pn = pn.next
117
+		ps = ps.next
118
+	}
119
+	return n
120
+}
121
+
122
+// Equal checks if this sequence is equal to the passed one
123
+func (s *sequence) equal(o *sequence) bool {
124
+	this := s
125
+	other := o
126
+	for this != nil {
127
+		if other == nil {
128
+			return false
129
+		}
130
+		if this.block != other.block || this.count != other.count {
131
+			return false
132
+		}
133
+		this = this.next
134
+		other = other.next
135
+	}
136
+	return other == nil
137
+}
138
+
139
+// ToByteArray converts the sequence into a byte array
140
+func (s *sequence) toByteArray() ([]byte, error) {
141
+	var bb []byte
142
+
143
+	p := s
144
+	b := make([]byte, 12)
145
+	for p != nil {
146
+		binary.BigEndian.PutUint32(b[0:], p.block)
147
+		binary.BigEndian.PutUint64(b[4:], p.count)
148
+		bb = append(bb, b...)
149
+		p = p.next
150
+	}
151
+
152
+	return bb, nil
153
+}
154
+
155
+// fromByteArray construct the sequence from the byte array
156
+func (s *sequence) fromByteArray(data []byte) error {
157
+	l := len(data)
158
+	if l%12 != 0 {
159
+		return fmt.Errorf("cannot deserialize byte sequence of length %d (%v)", l, data)
160
+	}
161
+
162
+	p := s
163
+	i := 0
164
+	for {
165
+		p.block = binary.BigEndian.Uint32(data[i : i+4])
166
+		p.count = binary.BigEndian.Uint64(data[i+4 : i+12])
167
+		i += 12
168
+		if i == l {
169
+			break
170
+		}
171
+		p.next = &sequence{}
172
+		p = p.next
173
+	}
174
+
175
+	return nil
176
+}
177
+
178
+// SetAnyInRange sets the first unset bit in the range [start, end) and returns
179
+// the ordinal of the set bit.
180
+//
181
+// When serial=true, the bitmap is scanned starting from the ordinal following
182
+// the bit most recently set by [Bitmap.SetAny] or [Bitmap.SetAnyInRange].
183
+func (h *Bitmap) SetAnyInRange(start, end uint64, serial bool) (uint64, error) {
184
+	if end < start || end >= h.bits {
185
+		return invalidPos, fmt.Errorf("invalid bit range [%d, %d)", start, end)
186
+	}
187
+	if h.Unselected() == 0 {
188
+		return invalidPos, ErrNoBitAvailable
189
+	}
190
+	return h.set(0, start, end, true, false, serial)
191
+}
192
+
193
+// SetAny sets the first unset bit in the sequence and returns the ordinal of
194
+// the set bit.
195
+//
196
+// When serial=true, the bitmap is scanned starting from the ordinal following
197
+// the bit most recently set by [Bitmap.SetAny] or [Bitmap.SetAnyInRange].
198
+func (h *Bitmap) SetAny(serial bool) (uint64, error) {
199
+	if h.Unselected() == 0 {
200
+		return invalidPos, ErrNoBitAvailable
201
+	}
202
+	return h.set(0, 0, h.bits-1, true, false, serial)
203
+}
204
+
205
+// Set atomically sets the corresponding bit in the sequence
206
+func (h *Bitmap) Set(ordinal uint64) error {
207
+	if err := h.validateOrdinal(ordinal); err != nil {
208
+		return err
209
+	}
210
+	_, err := h.set(ordinal, 0, 0, false, false, false)
211
+	return err
212
+}
213
+
214
+// Unset atomically unsets the corresponding bit in the sequence
215
+func (h *Bitmap) Unset(ordinal uint64) error {
216
+	if err := h.validateOrdinal(ordinal); err != nil {
217
+		return err
218
+	}
219
+	_, err := h.set(ordinal, 0, 0, false, true, false)
220
+	return err
221
+}
222
+
223
+// IsSet atomically checks if the ordinal bit is set. In case ordinal
224
+// is outside of the bit sequence limits, false is returned.
225
+func (h *Bitmap) IsSet(ordinal uint64) bool {
226
+	if err := h.validateOrdinal(ordinal); err != nil {
227
+		return false
228
+	}
229
+	_, _, err := checkIfAvailable(h.head, ordinal)
230
+	return err != nil
231
+}
232
+
233
+// CheckConsistency checks if the bit sequence is in an inconsistent state and attempts to fix it.
234
+// It looks for a corruption signature that may happen in docker 1.9.0 and 1.9.1.
235
+func (h *Bitmap) CheckConsistency() bool {
236
+	corrupted := false
237
+	for p, c := h.head, h.head.next; c != nil; c = c.next {
238
+		if c.count == 0 {
239
+			corrupted = true
240
+			p.next = c.next
241
+			continue // keep same p
242
+		}
243
+		p = c
244
+	}
245
+	return corrupted
246
+}
247
+
248
+// set/reset the bit
249
+func (h *Bitmap) set(ordinal, start, end uint64, any bool, release bool, serial bool) (uint64, error) {
250
+	var (
251
+		bitPos  uint64
252
+		bytePos uint64
253
+		ret     uint64
254
+		err     error
255
+	)
256
+
257
+	curr := uint64(0)
258
+	if serial {
259
+		curr = h.curr
260
+	}
261
+	// Get position if available
262
+	if release {
263
+		bytePos, bitPos = ordinalToPos(ordinal)
264
+	} else {
265
+		if any {
266
+			bytePos, bitPos, err = getAvailableFromCurrent(h.head, start, curr, end)
267
+			ret = posToOrdinal(bytePos, bitPos)
268
+			if err == nil {
269
+				h.curr = ret + 1
270
+			}
271
+		} else {
272
+			bytePos, bitPos, err = checkIfAvailable(h.head, ordinal)
273
+			ret = ordinal
274
+		}
275
+	}
276
+	if err != nil {
277
+		return ret, err
278
+	}
279
+
280
+	h.head = pushReservation(bytePos, bitPos, h.head, release)
281
+	if release {
282
+		h.unselected++
283
+	} else {
284
+		h.unselected--
285
+	}
286
+
287
+	return ret, nil
288
+}
289
+
290
+// checks is needed because to cover the case where the number of bits is not a multiple of blockLen
291
+func (h *Bitmap) validateOrdinal(ordinal uint64) error {
292
+	if ordinal >= h.bits {
293
+		return errors.New("bit does not belong to the sequence")
294
+	}
295
+	return nil
296
+}
297
+
298
+// MarshalBinary encodes h into a binary representation.
299
+func (h *Bitmap) MarshalBinary() ([]byte, error) {
300
+	ba := make([]byte, 16)
301
+	binary.BigEndian.PutUint64(ba[0:], h.bits)
302
+	binary.BigEndian.PutUint64(ba[8:], h.unselected)
303
+	bm, err := h.head.toByteArray()
304
+	if err != nil {
305
+		return nil, fmt.Errorf("failed to serialize head: %v", err)
306
+	}
307
+	ba = append(ba, bm...)
308
+
309
+	return ba, nil
310
+}
311
+
312
+// UnmarshalBinary decodes a binary representation of a Bitmap value which was
313
+// generated using [Bitmap.MarshalBinary].
314
+//
315
+// The scan position for serial [Bitmap.SetAny] and [Bitmap.SetAnyInRange]
316
+// operations is neither unmarshaled nor reset.
317
+func (h *Bitmap) UnmarshalBinary(ba []byte) error {
318
+	if ba == nil {
319
+		return errors.New("nil byte array")
320
+	}
321
+
322
+	nh := &sequence{}
323
+	err := nh.fromByteArray(ba[16:])
324
+	if err != nil {
325
+		return fmt.Errorf("failed to deserialize head: %v", err)
326
+	}
327
+
328
+	h.head = nh
329
+	h.bits = binary.BigEndian.Uint64(ba[0:8])
330
+	h.unselected = binary.BigEndian.Uint64(ba[8:16])
331
+	return nil
332
+}
333
+
334
+// Bits returns the length of the bit sequence
335
+func (h *Bitmap) Bits() uint64 {
336
+	return h.bits
337
+}
338
+
339
+// Unselected returns the number of bits which are not selected
340
+func (h *Bitmap) Unselected() uint64 {
341
+	return h.unselected
342
+}
343
+
344
+func (h *Bitmap) String() string {
345
+	return fmt.Sprintf("Bits: %d, Unselected: %d, Sequence: %s Curr:%d",
346
+		h.bits, h.unselected, h.head.toString(), h.curr)
347
+}
348
+
349
+// MarshalJSON encodes h into a JSON message
350
+func (h *Bitmap) MarshalJSON() ([]byte, error) {
351
+	b, err := h.MarshalBinary()
352
+	if err != nil {
353
+		return nil, err
354
+	}
355
+	return json.Marshal(b)
356
+}
357
+
358
+// UnmarshalJSON decodes JSON message into h
359
+func (h *Bitmap) UnmarshalJSON(data []byte) error {
360
+	var b []byte
361
+	if err := json.Unmarshal(data, &b); err != nil {
362
+		return err
363
+	}
364
+	return h.UnmarshalBinary(b)
365
+}
366
+
367
+// getFirstAvailable looks for the first unset bit in passed mask starting from start
368
+func getFirstAvailable(head *sequence, start uint64) (uint64, uint64, error) {
369
+	// Find sequence which contains the start bit
370
+	byteStart, bitStart := ordinalToPos(start)
371
+	current, _, precBlocks, inBlockBytePos := findSequence(head, byteStart)
372
+	// Derive the this sequence offsets
373
+	byteOffset := byteStart - inBlockBytePos
374
+	bitOffset := inBlockBytePos*8 + bitStart
375
+	for current != nil {
376
+		if current.block != blockMAX {
377
+			// If the current block is not full, check if there is any bit
378
+			// from the current bit in the current block. If not, before proceeding to the
379
+			// next block node, make sure we check for available bit in the next
380
+			// instance of the same block. Due to RLE same block signature will be
381
+			// compressed.
382
+		retry:
383
+			bytePos, bitPos, err := current.getAvailableBit(bitOffset)
384
+			if err != nil && precBlocks == current.count-1 {
385
+				// This is the last instance in the same block node,
386
+				// so move to the next block.
387
+				goto next
388
+			}
389
+			if err != nil {
390
+				// There are some more instances of the same block, so add the offset
391
+				// and be optimistic that you will find the available bit in the next
392
+				// instance of the same block.
393
+				bitOffset = 0
394
+				byteOffset += blockBytes
395
+				precBlocks++
396
+				goto retry
397
+			}
398
+			return byteOffset + bytePos, bitPos, err
399
+		}
400
+		// Moving to next block: Reset bit offset.
401
+	next:
402
+		bitOffset = 0
403
+		byteOffset += (current.count * blockBytes) - (precBlocks * blockBytes)
404
+		precBlocks = 0
405
+		current = current.next
406
+	}
407
+	return invalidPos, invalidPos, ErrNoBitAvailable
408
+}
409
+
410
+// getAvailableFromCurrent will look for available ordinal from the current ordinal.
411
+// If none found then it will loop back to the start to check of the available bit.
412
+// This can be further optimized to check from start till curr in case of a rollover
413
+func getAvailableFromCurrent(head *sequence, start, curr, end uint64) (uint64, uint64, error) {
414
+	var bytePos, bitPos uint64
415
+	var err error
416
+	if curr != 0 && curr > start {
417
+		bytePos, bitPos, err = getFirstAvailable(head, curr)
418
+		ret := posToOrdinal(bytePos, bitPos)
419
+		if end < ret || err != nil {
420
+			goto begin
421
+		}
422
+		return bytePos, bitPos, nil
423
+	}
424
+
425
+begin:
426
+	bytePos, bitPos, err = getFirstAvailable(head, start)
427
+	ret := posToOrdinal(bytePos, bitPos)
428
+	if end < ret || err != nil {
429
+		return invalidPos, invalidPos, ErrNoBitAvailable
430
+	}
431
+	return bytePos, bitPos, nil
432
+}
433
+
434
+// checkIfAvailable checks if the bit correspondent to the specified ordinal is unset
435
+// If the ordinal is beyond the sequence limits, a negative response is returned
436
+func checkIfAvailable(head *sequence, ordinal uint64) (uint64, uint64, error) {
437
+	bytePos, bitPos := ordinalToPos(ordinal)
438
+
439
+	// Find the sequence containing this byte
440
+	current, _, _, inBlockBytePos := findSequence(head, bytePos)
441
+	if current != nil {
442
+		// Check whether the bit corresponding to the ordinal address is unset
443
+		bitSel := blockFirstBit >> (inBlockBytePos*8 + bitPos)
444
+		if current.block&bitSel == 0 {
445
+			return bytePos, bitPos, nil
446
+		}
447
+	}
448
+
449
+	return invalidPos, invalidPos, ErrBitAllocated
450
+}
451
+
452
+// Given the byte position and the sequences list head, return the pointer to the
453
+// sequence containing the byte (current), the pointer to the previous sequence,
454
+// the number of blocks preceding the block containing the byte inside the current sequence.
455
+// If bytePos is outside of the list, function will return (nil, nil, 0, invalidPos)
456
+func findSequence(head *sequence, bytePos uint64) (*sequence, *sequence, uint64, uint64) {
457
+	// Find the sequence containing this byte
458
+	previous := head
459
+	current := head
460
+	n := bytePos
461
+	for current.next != nil && n >= (current.count*blockBytes) { // Nil check for less than 32 addresses masks
462
+		n -= (current.count * blockBytes)
463
+		previous = current
464
+		current = current.next
465
+	}
466
+
467
+	// If byte is outside of the list, let caller know
468
+	if n >= (current.count * blockBytes) {
469
+		return nil, nil, 0, invalidPos
470
+	}
471
+
472
+	// Find the byte position inside the block and the number of blocks
473
+	// preceding the block containing the byte inside this sequence
474
+	precBlocks := n / blockBytes
475
+	inBlockBytePos := bytePos % blockBytes
476
+
477
+	return current, previous, precBlocks, inBlockBytePos
478
+}
479
+
480
+// PushReservation pushes the bit reservation inside the bitmask.
481
+// Given byte and bit positions, identify the sequence (current) which holds the block containing the affected bit.
482
+// Create a new block with the modified bit according to the operation (allocate/release).
483
+// Create a new sequence containing the new block and insert it in the proper position.
484
+// Remove current sequence if empty.
485
+// Check if new sequence can be merged with neighbour (previous/next) sequences.
486
+//
487
+// Identify "current" sequence containing block:
488
+//
489
+//	[prev seq] [current seq] [next seq]
490
+//
491
+// Based on block position, resulting list of sequences can be any of three forms:
492
+//
493
+// block position                        Resulting list of sequences
494
+//
495
+// A) block is first in current:         [prev seq] [new] [modified current seq] [next seq]
496
+// B) block is last in current:          [prev seq] [modified current seq] [new] [next seq]
497
+// C) block is in the middle of current: [prev seq] [curr pre] [new] [curr post] [next seq]
498
+func pushReservation(bytePos, bitPos uint64, head *sequence, release bool) *sequence {
499
+	// Store list's head
500
+	newHead := head
501
+
502
+	// Find the sequence containing this byte
503
+	current, previous, precBlocks, inBlockBytePos := findSequence(head, bytePos)
504
+	if current == nil {
505
+		return newHead
506
+	}
507
+
508
+	// Construct updated block
509
+	bitSel := blockFirstBit >> (inBlockBytePos*8 + bitPos)
510
+	newBlock := current.block
511
+	if release {
512
+		newBlock &^= bitSel
513
+	} else {
514
+		newBlock |= bitSel
515
+	}
516
+
517
+	// Quit if it was a redundant request
518
+	if current.block == newBlock {
519
+		return newHead
520
+	}
521
+
522
+	// Current sequence inevitably looses one block, upadate count
523
+	current.count--
524
+
525
+	// Create new sequence
526
+	newSequence := &sequence{block: newBlock, count: 1}
527
+
528
+	// Insert the new sequence in the list based on block position
529
+	if precBlocks == 0 { // First in sequence (A)
530
+		newSequence.next = current
531
+		if current == head {
532
+			newHead = newSequence
533
+			previous = newHead
534
+		} else {
535
+			previous.next = newSequence
536
+		}
537
+		removeCurrentIfEmpty(&newHead, newSequence, current)
538
+		mergeSequences(previous)
539
+	} else if precBlocks == current.count { // Last in sequence (B)
540
+		newSequence.next = current.next
541
+		current.next = newSequence
542
+		mergeSequences(current)
543
+	} else { // In between the sequence (C)
544
+		currPre := &sequence{block: current.block, count: precBlocks, next: newSequence}
545
+		currPost := current
546
+		currPost.count -= precBlocks
547
+		newSequence.next = currPost
548
+		if currPost == head {
549
+			newHead = currPre
550
+		} else {
551
+			previous.next = currPre
552
+		}
553
+		// No merging or empty current possible here
554
+	}
555
+
556
+	return newHead
557
+}
558
+
559
+// Removes the current sequence from the list if empty, adjusting the head pointer if needed
560
+func removeCurrentIfEmpty(head **sequence, previous, current *sequence) {
561
+	if current.count == 0 {
562
+		if current == *head {
563
+			*head = current.next
564
+		} else {
565
+			previous.next = current.next
566
+		}
567
+	}
568
+}
569
+
570
+// Given a pointer to a sequence, it checks if it can be merged with any following sequences
571
+// It stops when no more merging is possible.
572
+// TODO: Optimization: only attempt merge from start to end sequence, no need to scan till the end of the list
573
+func mergeSequences(seq *sequence) {
574
+	if seq != nil {
575
+		// Merge all what possible from seq
576
+		for seq.next != nil && seq.block == seq.next.block {
577
+			seq.count += seq.next.count
578
+			seq.next = seq.next.next
579
+		}
580
+		// Move to next
581
+		mergeSequences(seq.next)
582
+	}
583
+}
584
+
585
+func getNumBlocks(numBits uint64) uint64 {
586
+	numBlocks := numBits / uint64(blockLen)
587
+	if numBits%uint64(blockLen) != 0 {
588
+		numBlocks++
589
+	}
590
+	return numBlocks
591
+}
592
+
593
+func ordinalToPos(ordinal uint64) (uint64, uint64) {
594
+	return ordinal / 8, ordinal % 8
595
+}
596
+
597
+func posToOrdinal(bytePos, bitPos uint64) uint64 {
598
+	return bytePos*8 + bitPos
599
+}
0 600
new file mode 100644
... ...
@@ -0,0 +1,1255 @@
0
+package bitmap
1
+
2
+import (
3
+	"math/rand"
4
+	"testing"
5
+	"time"
6
+)
7
+
8
+func TestSequenceGetAvailableBit(t *testing.T) {
9
+	input := []struct {
10
+		head    *sequence
11
+		from    uint64
12
+		bytePos uint64
13
+		bitPos  uint64
14
+	}{
15
+		{&sequence{block: 0x0, count: 0}, 0, invalidPos, invalidPos},
16
+		{&sequence{block: 0x0, count: 1}, 0, 0, 0},
17
+		{&sequence{block: 0x0, count: 100}, 0, 0, 0},
18
+
19
+		{&sequence{block: 0x80000000, count: 0}, 0, invalidPos, invalidPos},
20
+		{&sequence{block: 0x80000000, count: 1}, 0, 0, 1},
21
+		{&sequence{block: 0x80000000, count: 100}, 0, 0, 1},
22
+
23
+		{&sequence{block: 0xFF000000, count: 0}, 0, invalidPos, invalidPos},
24
+		{&sequence{block: 0xFF000000, count: 1}, 0, 1, 0},
25
+		{&sequence{block: 0xFF000000, count: 100}, 0, 1, 0},
26
+
27
+		{&sequence{block: 0xFF800000, count: 0}, 0, invalidPos, invalidPos},
28
+		{&sequence{block: 0xFF800000, count: 1}, 0, 1, 1},
29
+		{&sequence{block: 0xFF800000, count: 100}, 0, 1, 1},
30
+
31
+		{&sequence{block: 0xFFC0FF00, count: 0}, 0, invalidPos, invalidPos},
32
+		{&sequence{block: 0xFFC0FF00, count: 1}, 0, 1, 2},
33
+		{&sequence{block: 0xFFC0FF00, count: 100}, 0, 1, 2},
34
+
35
+		{&sequence{block: 0xFFE0FF00, count: 0}, 0, invalidPos, invalidPos},
36
+		{&sequence{block: 0xFFE0FF00, count: 1}, 0, 1, 3},
37
+		{&sequence{block: 0xFFE0FF00, count: 100}, 0, 1, 3},
38
+
39
+		{&sequence{block: 0xFFFEFF00, count: 0}, 0, invalidPos, invalidPos},
40
+		{&sequence{block: 0xFFFEFF00, count: 1}, 0, 1, 7},
41
+		{&sequence{block: 0xFFFEFF00, count: 100}, 0, 1, 7},
42
+
43
+		{&sequence{block: 0xFFFFC0FF, count: 0}, 0, invalidPos, invalidPos},
44
+		{&sequence{block: 0xFFFFC0FF, count: 1}, 0, 2, 2},
45
+		{&sequence{block: 0xFFFFC0FF, count: 100}, 0, 2, 2},
46
+
47
+		{&sequence{block: 0xFFFFFF00, count: 0}, 0, invalidPos, invalidPos},
48
+		{&sequence{block: 0xFFFFFF00, count: 1}, 0, 3, 0},
49
+		{&sequence{block: 0xFFFFFF00, count: 100}, 0, 3, 0},
50
+
51
+		{&sequence{block: 0xFFFFFFFE, count: 0}, 0, invalidPos, invalidPos},
52
+		{&sequence{block: 0xFFFFFFFE, count: 1}, 0, 3, 7},
53
+		{&sequence{block: 0xFFFFFFFE, count: 100}, 0, 3, 7},
54
+
55
+		{&sequence{block: 0xFFFFFFFF, count: 0}, 0, invalidPos, invalidPos},
56
+		{&sequence{block: 0xFFFFFFFF, count: 1}, 0, invalidPos, invalidPos},
57
+		{&sequence{block: 0xFFFFFFFF, count: 100}, 0, invalidPos, invalidPos},
58
+
59
+		// now test with offset
60
+		{&sequence{block: 0x0, count: 0}, 0, invalidPos, invalidPos},
61
+		{&sequence{block: 0x0, count: 0}, 31, invalidPos, invalidPos},
62
+		{&sequence{block: 0x0, count: 0}, 32, invalidPos, invalidPos},
63
+		{&sequence{block: 0x0, count: 1}, 0, 0, 0},
64
+		{&sequence{block: 0x0, count: 1}, 1, 0, 1},
65
+		{&sequence{block: 0x0, count: 1}, 31, 3, 7},
66
+		{&sequence{block: 0xF0FF0000, count: 1}, 0, 0, 4},
67
+		{&sequence{block: 0xF0FF0000, count: 1}, 8, 2, 0},
68
+		{&sequence{block: 0xFFFFFFFF, count: 1}, 0, invalidPos, invalidPos},
69
+		{&sequence{block: 0xFFFFFFFF, count: 1}, 16, invalidPos, invalidPos},
70
+		{&sequence{block: 0xFFFFFFFF, count: 1}, 31, invalidPos, invalidPos},
71
+		{&sequence{block: 0xFFFFFFFE, count: 1}, 0, 3, 7},
72
+		{&sequence{block: 0xFFFFFFFF, count: 2}, 0, invalidPos, invalidPos},
73
+		{&sequence{block: 0xFFFFFFFF, count: 2}, 32, invalidPos, invalidPos},
74
+	}
75
+
76
+	for n, i := range input {
77
+		b, bb, err := i.head.getAvailableBit(i.from)
78
+		if b != i.bytePos || bb != i.bitPos {
79
+			t.Fatalf("Error in sequence.getAvailableBit(%d) (%d).\nExp: (%d, %d)\nGot: (%d, %d), err: %v", i.from, n, i.bytePos, i.bitPos, b, bb, err)
80
+		}
81
+	}
82
+}
83
+
84
+func TestSequenceEqual(t *testing.T) {
85
+	input := []struct {
86
+		first    *sequence
87
+		second   *sequence
88
+		areEqual bool
89
+	}{
90
+		{&sequence{block: 0x0, count: 8, next: nil}, &sequence{block: 0x0, count: 8}, true},
91
+		{&sequence{block: 0x0, count: 0, next: nil}, &sequence{block: 0x0, count: 0}, true},
92
+		{&sequence{block: 0x0, count: 2, next: nil}, &sequence{block: 0x0, count: 1, next: &sequence{block: 0x0, count: 1}}, false},
93
+		{&sequence{block: 0x0, count: 2, next: &sequence{block: 0x1, count: 1}}, &sequence{block: 0x0, count: 2}, false},
94
+
95
+		{&sequence{block: 0x12345678, count: 8, next: nil}, &sequence{block: 0x12345678, count: 8}, true},
96
+		{&sequence{block: 0x12345678, count: 8, next: nil}, &sequence{block: 0x12345678, count: 9}, false},
97
+		{&sequence{block: 0x12345678, count: 1, next: &sequence{block: 0xFFFFFFFF, count: 1}}, &sequence{block: 0x12345678, count: 1}, false},
98
+		{&sequence{block: 0x12345678, count: 1}, &sequence{block: 0x12345678, count: 1, next: &sequence{block: 0xFFFFFFFF, count: 1}}, false},
99
+	}
100
+
101
+	for n, i := range input {
102
+		if i.areEqual != i.first.equal(i.second) {
103
+			t.Fatalf("Error in sequence.equal() (%d).\nExp: %t\nGot: %t,", n, i.areEqual, !i.areEqual)
104
+		}
105
+	}
106
+}
107
+
108
+func TestSequenceCopy(t *testing.T) {
109
+	s := getTestSequence()
110
+	n := s.getCopy()
111
+	if !s.equal(n) {
112
+		t.Fatal("copy of s failed")
113
+	}
114
+	if n == s {
115
+		t.Fatal("not true copy of s")
116
+	}
117
+}
118
+
119
+func TestGetFirstAvailable(t *testing.T) {
120
+	input := []struct {
121
+		mask    *sequence
122
+		bytePos uint64
123
+		bitPos  uint64
124
+		start   uint64
125
+	}{
126
+		{&sequence{block: 0xffffffff, count: 2048}, invalidPos, invalidPos, 0},
127
+		{&sequence{block: 0x0, count: 8}, 0, 0, 0},
128
+		{&sequence{block: 0x80000000, count: 8}, 0, 1, 0},
129
+		{&sequence{block: 0xC0000000, count: 8}, 0, 2, 0},
130
+		{&sequence{block: 0xE0000000, count: 8}, 0, 3, 0},
131
+		{&sequence{block: 0xF0000000, count: 8}, 0, 4, 0},
132
+		{&sequence{block: 0xF8000000, count: 8}, 0, 5, 0},
133
+		{&sequence{block: 0xFC000000, count: 8}, 0, 6, 0},
134
+		{&sequence{block: 0xFE000000, count: 8}, 0, 7, 0},
135
+		{&sequence{block: 0xFE000000, count: 8}, 3, 0, 24},
136
+
137
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x00000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 0, 0},
138
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 1, 0},
139
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 2, 0},
140
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xE0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 3, 0},
141
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 4, 0},
142
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF8000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 5, 0},
143
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFC000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 6, 0},
144
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFE000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 7, 0},
145
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x0E000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 0, 16},
146
+
147
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 0, 0},
148
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF800000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 1, 0},
149
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFC00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 2, 0},
150
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFE00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 3, 0},
151
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 4, 0},
152
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF80000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 5, 0},
153
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFC0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 6, 0},
154
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFE0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 7, 0},
155
+
156
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 7, 7, 0},
157
+
158
+		{&sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0x0, count: 6}}, 8, 0, 0},
159
+		{&sequence{block: 0xfffcffff, count: 1, next: &sequence{block: 0x0, count: 6}}, 4, 0, 16},
160
+		{&sequence{block: 0xfffcffff, count: 1, next: &sequence{block: 0x0, count: 6}}, 1, 7, 15},
161
+		{&sequence{block: 0xfffcffff, count: 1, next: &sequence{block: 0x0, count: 6}}, 1, 6, 10},
162
+		{&sequence{block: 0xfffcfffe, count: 1, next: &sequence{block: 0x0, count: 6}}, 3, 7, 31},
163
+		{&sequence{block: 0xfffcffff, count: 1, next: &sequence{block: 0xffffffff, count: 6}}, invalidPos, invalidPos, 31},
164
+	}
165
+
166
+	for n, i := range input {
167
+		bytePos, bitPos, _ := getFirstAvailable(i.mask, i.start)
168
+		if bytePos != i.bytePos || bitPos != i.bitPos {
169
+			t.Fatalf("Error in (%d) getFirstAvailable(). Expected (%d, %d). Got (%d, %d)", n, i.bytePos, i.bitPos, bytePos, bitPos)
170
+		}
171
+	}
172
+}
173
+
174
+func TestFindSequence(t *testing.T) {
175
+	input := []struct {
176
+		head           *sequence
177
+		bytePos        uint64
178
+		precBlocks     uint64
179
+		inBlockBytePos uint64
180
+	}{
181
+		{&sequence{block: 0xffffffff, count: 0}, 0, 0, invalidPos},
182
+		{&sequence{block: 0xffffffff, count: 0}, 31, 0, invalidPos},
183
+		{&sequence{block: 0xffffffff, count: 0}, 100, 0, invalidPos},
184
+
185
+		{&sequence{block: 0x0, count: 1}, 0, 0, 0},
186
+		{&sequence{block: 0x0, count: 1}, 1, 0, 1},
187
+		{&sequence{block: 0x0, count: 1}, 31, 0, invalidPos},
188
+		{&sequence{block: 0x0, count: 1}, 60, 0, invalidPos},
189
+
190
+		{&sequence{block: 0xffffffff, count: 10}, 0, 0, 0},
191
+		{&sequence{block: 0xffffffff, count: 10}, 3, 0, 3},
192
+		{&sequence{block: 0xffffffff, count: 10}, 4, 1, 0},
193
+		{&sequence{block: 0xffffffff, count: 10}, 7, 1, 3},
194
+		{&sequence{block: 0xffffffff, count: 10}, 8, 2, 0},
195
+		{&sequence{block: 0xffffffff, count: 10}, 39, 9, 3},
196
+
197
+		{&sequence{block: 0xffffffff, count: 10, next: &sequence{block: 0xcc000000, count: 10}}, 79, 9, 3},
198
+		{&sequence{block: 0xffffffff, count: 10, next: &sequence{block: 0xcc000000, count: 10}}, 80, 0, invalidPos},
199
+	}
200
+
201
+	for n, i := range input {
202
+		_, _, precBlocks, inBlockBytePos := findSequence(i.head, i.bytePos)
203
+		if precBlocks != i.precBlocks || inBlockBytePos != i.inBlockBytePos {
204
+			t.Fatalf("Error in (%d) findSequence(). Expected (%d, %d). Got (%d, %d)", n, i.precBlocks, i.inBlockBytePos, precBlocks, inBlockBytePos)
205
+		}
206
+	}
207
+}
208
+
209
+func TestCheckIfAvailable(t *testing.T) {
210
+	input := []struct {
211
+		head    *sequence
212
+		ordinal uint64
213
+		bytePos uint64
214
+		bitPos  uint64
215
+	}{
216
+		{&sequence{block: 0xffffffff, count: 0}, 0, invalidPos, invalidPos},
217
+		{&sequence{block: 0xffffffff, count: 0}, 31, invalidPos, invalidPos},
218
+		{&sequence{block: 0xffffffff, count: 0}, 100, invalidPos, invalidPos},
219
+
220
+		{&sequence{block: 0x0, count: 1}, 0, 0, 0},
221
+		{&sequence{block: 0x0, count: 1}, 1, 0, 1},
222
+		{&sequence{block: 0x0, count: 1}, 31, 3, 7},
223
+		{&sequence{block: 0x0, count: 1}, 60, invalidPos, invalidPos},
224
+
225
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x800000ff, count: 1}}, 31, invalidPos, invalidPos},
226
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x800000ff, count: 1}}, 32, invalidPos, invalidPos},
227
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x800000ff, count: 1}}, 33, 4, 1},
228
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1}}, 33, invalidPos, invalidPos},
229
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1}}, 34, 4, 2},
230
+
231
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1, next: &sequence{block: 0x0, count: 1}}}, 55, 6, 7},
232
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1, next: &sequence{block: 0x0, count: 1}}}, 56, invalidPos, invalidPos},
233
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1, next: &sequence{block: 0x0, count: 1}}}, 63, invalidPos, invalidPos},
234
+
235
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1, next: &sequence{block: 0x0, count: 1}}}, 64, 8, 0},
236
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1, next: &sequence{block: 0x0, count: 1}}}, 95, 11, 7},
237
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1, next: &sequence{block: 0x0, count: 1}}}, 96, invalidPos, invalidPos},
238
+	}
239
+
240
+	for n, i := range input {
241
+		bytePos, bitPos, err := checkIfAvailable(i.head, i.ordinal)
242
+		if bytePos != i.bytePos || bitPos != i.bitPos {
243
+			t.Fatalf("Error in (%d) checkIfAvailable(ord:%d). Expected (%d, %d). Got (%d, %d). err: %v", n, i.ordinal, i.bytePos, i.bitPos, bytePos, bitPos, err)
244
+		}
245
+	}
246
+}
247
+
248
+func TestMergeSequences(t *testing.T) {
249
+	input := []struct {
250
+		original *sequence
251
+		merged   *sequence
252
+	}{
253
+		{&sequence{block: 0xFE000000, count: 8, next: &sequence{block: 0xFE000000, count: 2}}, &sequence{block: 0xFE000000, count: 10}},
254
+		{&sequence{block: 0xFFFFFFFF, count: 8, next: &sequence{block: 0xFFFFFFFF, count: 1}}, &sequence{block: 0xFFFFFFFF, count: 9}},
255
+		{&sequence{block: 0xFFFFFFFF, count: 1, next: &sequence{block: 0xFFFFFFFF, count: 8}}, &sequence{block: 0xFFFFFFFF, count: 9}},
256
+
257
+		{&sequence{block: 0xFFFFFFF0, count: 8, next: &sequence{block: 0xFFFFFFF0, count: 1}}, &sequence{block: 0xFFFFFFF0, count: 9}},
258
+		{&sequence{block: 0xFFFFFFF0, count: 1, next: &sequence{block: 0xFFFFFFF0, count: 8}}, &sequence{block: 0xFFFFFFF0, count: 9}},
259
+
260
+		{&sequence{block: 0xFE, count: 8, next: &sequence{block: 0xFE, count: 1, next: &sequence{block: 0xFE, count: 5}}}, &sequence{block: 0xFE, count: 14}},
261
+		{&sequence{block: 0xFE, count: 8, next: &sequence{block: 0xFE, count: 1, next: &sequence{block: 0xFE, count: 5, next: &sequence{block: 0xFF, count: 1}}}},
262
+			&sequence{block: 0xFE, count: 14, next: &sequence{block: 0xFF, count: 1}}},
263
+
264
+		// No merge
265
+		{&sequence{block: 0xFE, count: 8, next: &sequence{block: 0xF8, count: 1, next: &sequence{block: 0xFE, count: 5}}},
266
+			&sequence{block: 0xFE, count: 8, next: &sequence{block: 0xF8, count: 1, next: &sequence{block: 0xFE, count: 5}}}},
267
+
268
+		// No merge from head: // Merge function tries to merge from passed head. If it can't merge with next, it does not reattempt with next as head
269
+		{&sequence{block: 0xFE, count: 8, next: &sequence{block: 0xFF, count: 1, next: &sequence{block: 0xFF, count: 5}}},
270
+			&sequence{block: 0xFE, count: 8, next: &sequence{block: 0xFF, count: 6}}},
271
+	}
272
+
273
+	for n, i := range input {
274
+		mergeSequences(i.original)
275
+		for !i.merged.equal(i.original) {
276
+			t.Fatalf("Error in (%d) mergeSequences().\nExp: %s\nGot: %s,", n, i.merged.toString(), i.original.toString())
277
+		}
278
+	}
279
+}
280
+
281
+func TestPushReservation(t *testing.T) {
282
+	input := []struct {
283
+		mask    *sequence
284
+		bytePos uint64
285
+		bitPos  uint64
286
+		newMask *sequence
287
+	}{
288
+		// Create first sequence and fill in 8 addresses starting from address 0
289
+		{&sequence{block: 0x0, count: 8, next: nil}, 0, 0, &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 7, next: nil}}},
290
+		{&sequence{block: 0x80000000, count: 8}, 0, 1, &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0x80000000, count: 7, next: nil}}},
291
+		{&sequence{block: 0xC0000000, count: 8}, 0, 2, &sequence{block: 0xE0000000, count: 1, next: &sequence{block: 0xC0000000, count: 7, next: nil}}},
292
+		{&sequence{block: 0xE0000000, count: 8}, 0, 3, &sequence{block: 0xF0000000, count: 1, next: &sequence{block: 0xE0000000, count: 7, next: nil}}},
293
+		{&sequence{block: 0xF0000000, count: 8}, 0, 4, &sequence{block: 0xF8000000, count: 1, next: &sequence{block: 0xF0000000, count: 7, next: nil}}},
294
+		{&sequence{block: 0xF8000000, count: 8}, 0, 5, &sequence{block: 0xFC000000, count: 1, next: &sequence{block: 0xF8000000, count: 7, next: nil}}},
295
+		{&sequence{block: 0xFC000000, count: 8}, 0, 6, &sequence{block: 0xFE000000, count: 1, next: &sequence{block: 0xFC000000, count: 7, next: nil}}},
296
+		{&sequence{block: 0xFE000000, count: 8}, 0, 7, &sequence{block: 0xFF000000, count: 1, next: &sequence{block: 0xFE000000, count: 7, next: nil}}},
297
+
298
+		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 7}}, 0, 1, &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0x0, count: 7, next: nil}}},
299
+
300
+		// Create second sequence and fill in 8 addresses starting from address 32
301
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x00000000, count: 1, next: &sequence{block: 0xffffffff, count: 6, next: nil}}}, 4, 0,
302
+			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
303
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 1,
304
+			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
305
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 2,
306
+			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xE0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
307
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xE0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 3,
308
+			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
309
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 4,
310
+			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF8000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
311
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF8000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 5,
312
+			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFC000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
313
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFC000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 6,
314
+			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFE000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
315
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFE000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 7,
316
+			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
317
+		// fill in 8 addresses starting from address 40
318
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 0,
319
+			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF800000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
320
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF800000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 1,
321
+			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFC00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
322
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFC00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 2,
323
+			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFE00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
324
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFE00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 3,
325
+			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
326
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 4,
327
+			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF80000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
328
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF80000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 5,
329
+			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFC0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
330
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFC0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 6,
331
+			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFE0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
332
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFE0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 7,
333
+			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFF0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
334
+
335
+		// Insert new sequence
336
+		{&sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0x0, count: 6}}, 8, 0,
337
+			&sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5}}}},
338
+		{&sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5}}}, 8, 1,
339
+			&sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0x0, count: 5}}}},
340
+
341
+		// Merge affected with next
342
+		{&sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 2, next: &sequence{block: 0xffffffff, count: 1}}}, 31, 7,
343
+			&sequence{block: 0xffffffff, count: 8, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 1}}}},
344
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xfffffffc, count: 1, next: &sequence{block: 0xfffffffe, count: 6}}}, 7, 6,
345
+			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xfffffffe, count: 7}}},
346
+
347
+		// Merge affected with next and next.next
348
+		{&sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 1}}}, 31, 7,
349
+			&sequence{block: 0xffffffff, count: 9}},
350
+		{&sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 1}}, 31, 7,
351
+			&sequence{block: 0xffffffff, count: 8}},
352
+
353
+		// Merge affected with previous and next
354
+		{&sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 1}}}, 31, 7,
355
+			&sequence{block: 0xffffffff, count: 9}},
356
+
357
+		// Redundant push: No change
358
+		{&sequence{block: 0xffff0000, count: 1}, 0, 0, &sequence{block: 0xffff0000, count: 1}},
359
+		{&sequence{block: 0xffff0000, count: 7}, 25, 7, &sequence{block: 0xffff0000, count: 7}},
360
+		{&sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 1}}}, 7, 7,
361
+			&sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 1}}}},
362
+
363
+		// Set last bit
364
+		{&sequence{block: 0x0, count: 8}, 31, 7, &sequence{block: 0x0, count: 7, next: &sequence{block: 0x1, count: 1}}},
365
+
366
+		// Set bit in a middle sequence in the first block, first bit
367
+		{&sequence{block: 0x40000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 4, 0,
368
+			&sequence{block: 0x40000000, count: 1, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5,
369
+				next: &sequence{block: 0x1, count: 1}}}}},
370
+
371
+		// Set bit in a middle sequence in the first block, first bit (merge involved)
372
+		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 4, 0,
373
+			&sequence{block: 0x80000000, count: 2, next: &sequence{block: 0x0, count: 5, next: &sequence{block: 0x1, count: 1}}}},
374
+
375
+		// Set bit in a middle sequence in the first block, last bit
376
+		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 4, 31,
377
+			&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x1, count: 1, next: &sequence{block: 0x0, count: 5,
378
+				next: &sequence{block: 0x1, count: 1}}}}},
379
+
380
+		// Set bit in a middle sequence in the first block, middle bit
381
+		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 4, 16,
382
+			&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x8000, count: 1, next: &sequence{block: 0x0, count: 5,
383
+				next: &sequence{block: 0x1, count: 1}}}}},
384
+
385
+		// Set bit in a middle sequence in a middle block, first bit
386
+		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 16, 0,
387
+			&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 3, next: &sequence{block: 0x80000000, count: 1,
388
+				next: &sequence{block: 0x0, count: 2, next: &sequence{block: 0x1, count: 1}}}}}},
389
+
390
+		// Set bit in a middle sequence in a middle block, last bit
391
+		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 16, 31,
392
+			&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 3, next: &sequence{block: 0x1, count: 1,
393
+				next: &sequence{block: 0x0, count: 2, next: &sequence{block: 0x1, count: 1}}}}}},
394
+
395
+		// Set bit in a middle sequence in a middle block, middle bit
396
+		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 16, 15,
397
+			&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 3, next: &sequence{block: 0x10000, count: 1,
398
+				next: &sequence{block: 0x0, count: 2, next: &sequence{block: 0x1, count: 1}}}}}},
399
+
400
+		// Set bit in a middle sequence in the last block, first bit
401
+		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 24, 0,
402
+			&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5, next: &sequence{block: 0x80000000, count: 1,
403
+				next: &sequence{block: 0x1, count: 1}}}}},
404
+
405
+		// Set bit in a middle sequence in the last block, last bit
406
+		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x4, count: 1}}}, 24, 31,
407
+			&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5, next: &sequence{block: 0x1, count: 1,
408
+				next: &sequence{block: 0x4, count: 1}}}}},
409
+
410
+		// Set bit in a middle sequence in the last block, last bit (merge involved)
411
+		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 24, 31,
412
+			&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5, next: &sequence{block: 0x1, count: 2}}}},
413
+
414
+		// Set bit in a middle sequence in the last block, middle bit
415
+		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 24, 16,
416
+			&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5, next: &sequence{block: 0x8000, count: 1,
417
+				next: &sequence{block: 0x1, count: 1}}}}},
418
+	}
419
+
420
+	for n, i := range input {
421
+		mask := pushReservation(i.bytePos, i.bitPos, i.mask, false)
422
+		if !mask.equal(i.newMask) {
423
+			t.Fatalf("Error in (%d) pushReservation():\n%s + (%d,%d):\nExp: %s\nGot: %s,",
424
+				n, i.mask.toString(), i.bytePos, i.bitPos, i.newMask.toString(), mask.toString())
425
+		}
426
+	}
427
+}
428
+
429
+func TestSerializeDeserialize(t *testing.T) {
430
+	s := getTestSequence()
431
+
432
+	data, err := s.toByteArray()
433
+	if err != nil {
434
+		t.Fatal(err)
435
+	}
436
+
437
+	r := &sequence{}
438
+	err = r.fromByteArray(data)
439
+	if err != nil {
440
+		t.Fatal(err)
441
+	}
442
+
443
+	if !s.equal(r) {
444
+		t.Fatalf("Sequences are different: \n%v\n%v", s, r)
445
+	}
446
+}
447
+
448
+func getTestSequence() *sequence {
449
+	// Returns a custom sequence of 1024 * 32 bits
450
+	return &sequence{
451
+		block: 0xFFFFFFFF,
452
+		count: 100,
453
+		next: &sequence{
454
+			block: 0xFFFFFFFE,
455
+			count: 1,
456
+			next: &sequence{
457
+				block: 0xFF000000,
458
+				count: 10,
459
+				next: &sequence{
460
+					block: 0xFFFFFFFF,
461
+					count: 50,
462
+					next: &sequence{
463
+						block: 0xFFFFFFFC,
464
+						count: 1,
465
+						next: &sequence{
466
+							block: 0xFF800000,
467
+							count: 1,
468
+							next: &sequence{
469
+								block: 0xFFFFFFFF,
470
+								count: 87,
471
+								next: &sequence{
472
+									block: 0x0,
473
+									count: 150,
474
+									next: &sequence{
475
+										block: 0xFFFFFFFF,
476
+										count: 200,
477
+										next: &sequence{
478
+											block: 0x0000FFFF,
479
+											count: 1,
480
+											next: &sequence{
481
+												block: 0x0,
482
+												count: 399,
483
+												next: &sequence{
484
+													block: 0xFFFFFFFF,
485
+													count: 23,
486
+													next: &sequence{
487
+														block: 0x1,
488
+														count: 1,
489
+													},
490
+												},
491
+											},
492
+										},
493
+									},
494
+								},
495
+							},
496
+						},
497
+					},
498
+				},
499
+			},
500
+		},
501
+	}
502
+}
503
+
504
+func TestSet(t *testing.T) {
505
+	hnd := New(1024 * 32)
506
+	hnd.head = getTestSequence()
507
+
508
+	firstAv := uint64(32*100 + 31)
509
+	last := uint64(1024*32 - 1)
510
+
511
+	if hnd.IsSet(100000) {
512
+		t.Fatal("IsSet() returned wrong result")
513
+	}
514
+
515
+	if !hnd.IsSet(0) {
516
+		t.Fatal("IsSet() returned wrong result")
517
+	}
518
+
519
+	if hnd.IsSet(firstAv) {
520
+		t.Fatal("IsSet() returned wrong result")
521
+	}
522
+
523
+	if !hnd.IsSet(last) {
524
+		t.Fatal("IsSet() returned wrong result")
525
+	}
526
+
527
+	if err := hnd.Set(0); err == nil {
528
+		t.Fatal("Expected failure, but succeeded")
529
+	}
530
+
531
+	os, err := hnd.SetAny(false)
532
+	if err != nil {
533
+		t.Fatalf("Unexpected failure: %v", err)
534
+	}
535
+	if os != firstAv {
536
+		t.Fatalf("SetAny returned unexpected ordinal. Expected %d. Got %d.", firstAv, os)
537
+	}
538
+	if !hnd.IsSet(firstAv) {
539
+		t.Fatal("IsSet() returned wrong result")
540
+	}
541
+
542
+	if err := hnd.Unset(firstAv); err != nil {
543
+		t.Fatalf("Unexpected failure: %v", err)
544
+	}
545
+
546
+	if hnd.IsSet(firstAv) {
547
+		t.Fatal("IsSet() returned wrong result")
548
+	}
549
+
550
+	if err := hnd.Set(firstAv); err != nil {
551
+		t.Fatalf("Unexpected failure: %v", err)
552
+	}
553
+
554
+	if err := hnd.Set(last); err == nil {
555
+		t.Fatal("Expected failure, but succeeded")
556
+	}
557
+}
558
+
559
+func TestSetUnset(t *testing.T) {
560
+	numBits := uint64(32 * blockLen)
561
+	hnd := New(numBits)
562
+
563
+	if err := hnd.Set(uint64(32 * blockLen)); err == nil {
564
+		t.Fatal("Expected failure, but succeeded")
565
+	}
566
+	if err := hnd.Unset(uint64(32 * blockLen)); err == nil {
567
+		t.Fatal("Expected failure, but succeeded")
568
+	}
569
+
570
+	// set and unset all one by one
571
+	for hnd.Unselected() > 0 {
572
+		if _, err := hnd.SetAny(false); err != nil {
573
+			t.Fatal(err)
574
+		}
575
+	}
576
+	if _, err := hnd.SetAny(false); err != ErrNoBitAvailable {
577
+		t.Fatal("Expected error. Got success")
578
+	}
579
+	if _, err := hnd.SetAnyInRange(10, 20, false); err != ErrNoBitAvailable {
580
+		t.Fatal("Expected error. Got success")
581
+	}
582
+	if err := hnd.Set(50); err != ErrBitAllocated {
583
+		t.Fatalf("Expected error. Got %v: %s", err, hnd)
584
+	}
585
+	i := uint64(0)
586
+	for hnd.Unselected() < numBits {
587
+		if err := hnd.Unset(i); err != nil {
588
+			t.Fatal(err)
589
+		}
590
+		i++
591
+	}
592
+}
593
+
594
+func TestOffsetSetUnset(t *testing.T) {
595
+	numBits := uint64(32 * blockLen)
596
+	hnd := New(numBits)
597
+
598
+	// set and unset all one by one
599
+	for hnd.Unselected() > 0 {
600
+		if _, err := hnd.SetAny(false); err != nil {
601
+			t.Fatal(err)
602
+		}
603
+	}
604
+
605
+	if _, err := hnd.SetAny(false); err != ErrNoBitAvailable {
606
+		t.Fatal("Expected error. Got success")
607
+	}
608
+
609
+	if _, err := hnd.SetAnyInRange(10, 20, false); err != ErrNoBitAvailable {
610
+		t.Fatal("Expected error. Got success")
611
+	}
612
+
613
+	if err := hnd.Unset(288); err != nil {
614
+		t.Fatal(err)
615
+	}
616
+
617
+	//At this point sequence is (0xffffffff, 9)->(0x7fffffff, 1)->(0xffffffff, 22)->end
618
+	o, err := hnd.SetAnyInRange(32, 500, false)
619
+	if err != nil {
620
+		t.Fatal(err)
621
+	}
622
+
623
+	if o != 288 {
624
+		t.Fatalf("Expected ordinal not received, Received:%d", o)
625
+	}
626
+}
627
+
628
+func TestSetInRange(t *testing.T) {
629
+	numBits := uint64(1024 * blockLen)
630
+	hnd := New(numBits)
631
+	hnd.head = getTestSequence()
632
+
633
+	firstAv := uint64(100*blockLen + blockLen - 1)
634
+
635
+	if o, err := hnd.SetAnyInRange(4, 3, false); err == nil {
636
+		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
637
+	}
638
+
639
+	if o, err := hnd.SetAnyInRange(0, numBits, false); err == nil {
640
+		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
641
+	}
642
+
643
+	o, err := hnd.SetAnyInRange(100*uint64(blockLen), 101*uint64(blockLen), false)
644
+	if err != nil {
645
+		t.Fatalf("Unexpected failure: (%d, %v)", o, err)
646
+	}
647
+	if o != firstAv {
648
+		t.Fatalf("Unexpected ordinal: %d", o)
649
+	}
650
+
651
+	if o, err := hnd.SetAnyInRange(0, uint64(blockLen), false); err == nil {
652
+		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
653
+	}
654
+
655
+	if o, err := hnd.SetAnyInRange(0, firstAv-1, false); err == nil {
656
+		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
657
+	}
658
+
659
+	if o, err := hnd.SetAnyInRange(111*uint64(blockLen), 161*uint64(blockLen), false); err == nil {
660
+		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
661
+	}
662
+
663
+	o, err = hnd.SetAnyInRange(161*uint64(blockLen), 162*uint64(blockLen), false)
664
+	if err != nil {
665
+		t.Fatal(err)
666
+	}
667
+	if o != 161*uint64(blockLen)+30 {
668
+		t.Fatalf("Unexpected ordinal: %d", o)
669
+	}
670
+
671
+	o, err = hnd.SetAnyInRange(161*uint64(blockLen), 162*uint64(blockLen), false)
672
+	if err != nil {
673
+		t.Fatal(err)
674
+	}
675
+	if o != 161*uint64(blockLen)+31 {
676
+		t.Fatalf("Unexpected ordinal: %d", o)
677
+	}
678
+
679
+	o, err = hnd.SetAnyInRange(161*uint64(blockLen), 162*uint64(blockLen), false)
680
+	if err == nil {
681
+		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
682
+	}
683
+
684
+	if _, err := hnd.SetAnyInRange(0, numBits-1, false); err != nil {
685
+		t.Fatalf("Unexpected failure: %v", err)
686
+	}
687
+
688
+	// set one bit using the set range with 1 bit size range
689
+	if _, err := hnd.SetAnyInRange(uint64(163*blockLen-1), uint64(163*blockLen-1), false); err != nil {
690
+		t.Fatal(err)
691
+	}
692
+
693
+	// create a non multiple of 32 mask
694
+	hnd = New(30)
695
+
696
+	// set all bit in the first range
697
+	for hnd.Unselected() > 22 {
698
+		if o, err := hnd.SetAnyInRange(0, 7, false); err != nil {
699
+			t.Fatalf("Unexpected failure: (%d, %v)", o, err)
700
+		}
701
+	}
702
+	// try one more set, which should fail
703
+	o, err = hnd.SetAnyInRange(0, 7, false)
704
+	if err == nil {
705
+		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
706
+	}
707
+	if err != ErrNoBitAvailable {
708
+		t.Fatalf("Unexpected error: %v", err)
709
+	}
710
+
711
+	// set all bit in a second range
712
+	for hnd.Unselected() > 14 {
713
+		if o, err := hnd.SetAnyInRange(8, 15, false); err != nil {
714
+			t.Fatalf("Unexpected failure: (%d, %v)", o, err)
715
+		}
716
+	}
717
+
718
+	// try one more set, which should fail
719
+	o, err = hnd.SetAnyInRange(0, 15, false)
720
+	if err == nil {
721
+		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
722
+	}
723
+	if err != ErrNoBitAvailable {
724
+		t.Fatalf("Unexpected error: %v", err)
725
+	}
726
+
727
+	// set all bit in a range which includes the last bit
728
+	for hnd.Unselected() > 12 {
729
+		if o, err := hnd.SetAnyInRange(28, 29, false); err != nil {
730
+			t.Fatalf("Unexpected failure: (%d, %v)", o, err)
731
+		}
732
+	}
733
+	o, err = hnd.SetAnyInRange(28, 29, false)
734
+	if err == nil {
735
+		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
736
+	}
737
+	if err != ErrNoBitAvailable {
738
+		t.Fatalf("Unexpected error: %v", err)
739
+	}
740
+}
741
+
742
+// This one tests an allocation pattern which unveiled an issue in pushReservation
743
+// Specifically a failure in detecting when we are in the (B) case (the bit to set
744
+// belongs to the last block of the current sequence). Because of a bug, code
745
+// was assuming the bit belonged to a block in the middle of the current sequence.
746
+// Which in turn caused an incorrect allocation when requesting a bit which is not
747
+// in the first or last sequence block.
748
+func TestSetAnyInRange(t *testing.T) {
749
+	numBits := uint64(8 * blockLen)
750
+	hnd := New(numBits)
751
+
752
+	if err := hnd.Set(0); err != nil {
753
+		t.Fatal(err)
754
+	}
755
+
756
+	if err := hnd.Set(255); err != nil {
757
+		t.Fatal(err)
758
+	}
759
+
760
+	o, err := hnd.SetAnyInRange(128, 255, false)
761
+	if err != nil {
762
+		t.Fatal(err)
763
+	}
764
+	if o != 128 {
765
+		t.Fatalf("Unexpected ordinal: %d", o)
766
+	}
767
+
768
+	o, err = hnd.SetAnyInRange(128, 255, false)
769
+	if err != nil {
770
+		t.Fatal(err)
771
+	}
772
+
773
+	if o != 129 {
774
+		t.Fatalf("Unexpected ordinal: %d", o)
775
+	}
776
+
777
+	o, err = hnd.SetAnyInRange(246, 255, false)
778
+	if err != nil {
779
+		t.Fatal(err)
780
+	}
781
+	if o != 246 {
782
+		t.Fatalf("Unexpected ordinal: %d", o)
783
+	}
784
+
785
+	o, err = hnd.SetAnyInRange(246, 255, false)
786
+	if err != nil {
787
+		t.Fatal(err)
788
+	}
789
+	if o != 247 {
790
+		t.Fatalf("Unexpected ordinal: %d", o)
791
+	}
792
+}
793
+
794
+func TestMethods(t *testing.T) {
795
+	numBits := uint64(256 * blockLen)
796
+	hnd := New(numBits)
797
+
798
+	if hnd.Bits() != numBits {
799
+		t.Fatalf("Unexpected bit number: %d", hnd.Bits())
800
+	}
801
+
802
+	if hnd.Unselected() != numBits {
803
+		t.Fatalf("Unexpected bit number: %d", hnd.Unselected())
804
+	}
805
+
806
+	exp := "(0x0, 256)->end"
807
+	if hnd.head.toString() != exp {
808
+		t.Fatalf("Unexpected sequence string: %s", hnd.head.toString())
809
+	}
810
+
811
+	for i := 0; i < 192; i++ {
812
+		_, err := hnd.SetAny(false)
813
+		if err != nil {
814
+			t.Fatal(err)
815
+		}
816
+	}
817
+
818
+	exp = "(0xffffffff, 6)->(0x0, 250)->end"
819
+	if hnd.head.toString() != exp {
820
+		t.Fatalf("Unexpected sequence string: %s", hnd.head.toString())
821
+	}
822
+}
823
+
824
+func TestRandomAllocateDeallocate(t *testing.T) {
825
+	numBits := int(16 * blockLen)
826
+	hnd := New(uint64(numBits))
827
+
828
+	seed := time.Now().Unix()
829
+	rand.Seed(seed)
830
+
831
+	// Allocate all bits using a random pattern
832
+	pattern := rand.Perm(numBits)
833
+	for _, bit := range pattern {
834
+		err := hnd.Set(uint64(bit))
835
+		if err != nil {
836
+			t.Fatalf("Unexpected failure on allocation of %d: %v.\nSeed: %d.\n%s", bit, err, seed, hnd)
837
+		}
838
+	}
839
+	if hnd.Unselected() != 0 {
840
+		t.Fatalf("Expected full sequence. Instead found %d free bits. Seed: %d.\n%s", hnd.unselected, seed, hnd)
841
+	}
842
+	if hnd.head.toString() != "(0xffffffff, 16)->end" {
843
+		t.Fatalf("Unexpected db: %s", hnd.head.toString())
844
+	}
845
+
846
+	// Deallocate all bits using a random pattern
847
+	pattern = rand.Perm(numBits)
848
+	for _, bit := range pattern {
849
+		err := hnd.Unset(uint64(bit))
850
+		if err != nil {
851
+			t.Fatalf("Unexpected failure on deallocation of %d: %v.\nSeed: %d.\n%s", bit, err, seed, hnd)
852
+		}
853
+	}
854
+	if hnd.Unselected() != uint64(numBits) {
855
+		t.Fatalf("Expected full sequence. Instead found %d free bits. Seed: %d.\n%s", hnd.unselected, seed, hnd)
856
+	}
857
+	if hnd.head.toString() != "(0x0, 16)->end" {
858
+		t.Fatalf("Unexpected db: %s", hnd.head.toString())
859
+	}
860
+}
861
+
862
+func TestAllocateRandomDeallocate(t *testing.T) {
863
+	numBlocks := uint32(8)
864
+	numBits := int(numBlocks * blockLen)
865
+	hnd := New(uint64(numBits))
866
+
867
+	expected := &sequence{block: 0xffffffff, count: uint64(numBlocks / 2), next: &sequence{block: 0x0, count: uint64(numBlocks / 2)}}
868
+
869
+	// Allocate first half of the bits
870
+	for i := 0; i < numBits/2; i++ {
871
+		_, err := hnd.SetAny(false)
872
+		if err != nil {
873
+			t.Fatalf("Unexpected failure on allocation %d: %v\n%s", i, err, hnd)
874
+		}
875
+	}
876
+	if hnd.Unselected() != uint64(numBits/2) {
877
+		t.Fatalf("Expected full sequence. Instead found %d free bits. %s", hnd.unselected, hnd)
878
+	}
879
+	if !hnd.head.equal(expected) {
880
+		t.Fatalf("Unexpected sequence. Got:\n%s", hnd)
881
+	}
882
+
883
+	seed := time.Now().Unix()
884
+	rand.Seed(seed)
885
+
886
+	// Deallocate half of the allocated bits following a random pattern
887
+	pattern := rand.Perm(numBits / 2)
888
+	for i := 0; i < numBits/4; i++ {
889
+		bit := pattern[i]
890
+		err := hnd.Unset(uint64(bit))
891
+		if err != nil {
892
+			t.Fatalf("Unexpected failure on deallocation of %d: %v.\nSeed: %d.\n%s", bit, err, seed, hnd)
893
+		}
894
+	}
895
+	if hnd.Unselected() != uint64(3*numBits/4) {
896
+		t.Fatalf("Expected full sequence. Instead found %d free bits.\nSeed: %d.\n%s", hnd.unselected, seed, hnd)
897
+	}
898
+
899
+	// Request a quarter of bits
900
+	for i := 0; i < numBits/4; i++ {
901
+		_, err := hnd.SetAny(false)
902
+		if err != nil {
903
+			t.Fatalf("Unexpected failure on allocation %d: %v\nSeed: %d\n%s", i, err, seed, hnd)
904
+		}
905
+	}
906
+	if hnd.Unselected() != uint64(numBits/2) {
907
+		t.Fatalf("Expected half sequence. Instead found %d free bits.\nSeed: %d\n%s", hnd.unselected, seed, hnd)
908
+	}
909
+	if !hnd.head.equal(expected) {
910
+		t.Fatalf("Unexpected sequence. Got:\n%s", hnd)
911
+	}
912
+}
913
+
914
+func TestAllocateRandomDeallocateSerialize(t *testing.T) {
915
+
916
+	numBlocks := uint32(8)
917
+	numBits := int(numBlocks * blockLen)
918
+	hnd := New(uint64(numBits))
919
+
920
+	expected := &sequence{block: 0xffffffff, count: uint64(numBlocks / 2), next: &sequence{block: 0x0, count: uint64(numBlocks / 2)}}
921
+
922
+	// Allocate first half of the bits
923
+	for i := 0; i < numBits/2; i++ {
924
+		_, err := hnd.SetAny(true)
925
+		if err != nil {
926
+			t.Fatalf("Unexpected failure on allocation %d: %v\n%s", i, err, hnd)
927
+		}
928
+	}
929
+
930
+	if hnd.Unselected() != uint64(numBits/2) {
931
+		t.Fatalf("Expected full sequence. Instead found %d free bits. %s", hnd.unselected, hnd)
932
+	}
933
+	if !hnd.head.equal(expected) {
934
+		t.Fatalf("Unexpected sequence. Got:\n%s", hnd)
935
+	}
936
+
937
+	seed := time.Now().Unix()
938
+	rand.Seed(seed)
939
+
940
+	// Deallocate half of the allocated bits following a random pattern
941
+	pattern := rand.Perm(numBits / 2)
942
+	for i := 0; i < numBits/4; i++ {
943
+		bit := pattern[i]
944
+		err := hnd.Unset(uint64(bit))
945
+		if err != nil {
946
+			t.Fatalf("Unexpected failure on deallocation of %d: %v.\nSeed: %d.\n%s", bit, err, seed, hnd)
947
+		}
948
+	}
949
+	if hnd.Unselected() != uint64(3*numBits/4) {
950
+		t.Fatalf("Expected full sequence. Instead found %d free bits.\nSeed: %d.\n%s", hnd.unselected, seed, hnd)
951
+	}
952
+
953
+	// Request a quarter of bits
954
+	for i := 0; i < numBits/4; i++ {
955
+		_, err := hnd.SetAny(true)
956
+		if err != nil {
957
+			t.Fatalf("Unexpected failure on allocation %d: %v\nSeed: %d\n%s", i, err, seed, hnd)
958
+		}
959
+	}
960
+	if hnd.Unselected() != uint64(numBits/2) {
961
+		t.Fatalf("Expected half sequence. Instead found %d free bits.\nSeed: %d\n%s", hnd.unselected, seed, hnd)
962
+	}
963
+}
964
+
965
+func TestIsCorrupted(t *testing.T) {
966
+	// Negative test
967
+	hnd := New(1024)
968
+
969
+	if hnd.CheckConsistency() {
970
+		t.Fatalf("Unexpected corrupted for %s", hnd)
971
+	}
972
+
973
+	hnd.Set(0)
974
+	if hnd.CheckConsistency() {
975
+		t.Fatalf("Unexpected corrupted for %s", hnd)
976
+	}
977
+
978
+	hnd.Set(1023)
979
+	if hnd.CheckConsistency() {
980
+		t.Fatalf("Unexpected corrupted for %s", hnd)
981
+	}
982
+
983
+	// Try real corrupted ipam handles found in the local store files reported by three docker users,
984
+	// plus a generic ipam handle from docker 1.9.1. This last will fail as well, because of how the
985
+	// last node in the sequence is expressed (This is true for IPAM handle only, because of the broadcast
986
+	// address reservation: last bit). This will allow an application using bitseq that runs a consistency
987
+	// check to detect and replace the 1.9.0/1 old vulnerable handle with the new one.
988
+	input := []*Bitmap{
989
+		{
990
+			bits:       65536,
991
+			unselected: 65412,
992
+			head: &sequence{
993
+				block: 0xffffffff,
994
+				count: 3,
995
+				next: &sequence{
996
+					block: 0xffffffbf,
997
+					count: 0,
998
+					next: &sequence{
999
+						block: 0xfe98816e,
1000
+						count: 1,
1001
+						next: &sequence{
1002
+							block: 0xffffffff,
1003
+							count: 0,
1004
+							next: &sequence{
1005
+								block: 0xe3bc0000,
1006
+								count: 1,
1007
+								next: &sequence{
1008
+									block: 0x0,
1009
+									count: 2042,
1010
+									next: &sequence{
1011
+										block: 0x1, count: 1,
1012
+										next: &sequence{
1013
+											block: 0x0, count: 0,
1014
+										},
1015
+									},
1016
+								},
1017
+							},
1018
+						},
1019
+					},
1020
+				},
1021
+			},
1022
+		},
1023
+		{
1024
+			bits:       65536,
1025
+			unselected: 65319,
1026
+			head: &sequence{
1027
+				block: 0xffffffff,
1028
+				count: 7,
1029
+				next: &sequence{
1030
+					block: 0xffffff7f,
1031
+					count: 0,
1032
+					next: &sequence{
1033
+						block: 0xffffffff,
1034
+						count: 0,
1035
+						next: &sequence{
1036
+							block: 0x2000000,
1037
+							count: 1,
1038
+							next: &sequence{
1039
+								block: 0x0,
1040
+								count: 2039,
1041
+								next: &sequence{
1042
+									block: 0x1,
1043
+									count: 1,
1044
+									next: &sequence{
1045
+										block: 0x0,
1046
+										count: 0,
1047
+									},
1048
+								},
1049
+							},
1050
+						},
1051
+					},
1052
+				},
1053
+			},
1054
+		},
1055
+		{
1056
+			bits:       65536,
1057
+			unselected: 65456,
1058
+			head: &sequence{
1059
+				block: 0xffffffff, count: 2,
1060
+				next: &sequence{
1061
+					block: 0xfffbffff, count: 0,
1062
+					next: &sequence{
1063
+						block: 0xffd07000, count: 1,
1064
+						next: &sequence{
1065
+							block: 0x0, count: 333,
1066
+							next: &sequence{
1067
+								block: 0x40000000, count: 1,
1068
+								next: &sequence{
1069
+									block: 0x0, count: 1710,
1070
+									next: &sequence{
1071
+										block: 0x1, count: 1,
1072
+										next: &sequence{
1073
+											block: 0x0, count: 0,
1074
+										},
1075
+									},
1076
+								},
1077
+							},
1078
+						},
1079
+					},
1080
+				},
1081
+			},
1082
+		},
1083
+	}
1084
+
1085
+	for idx, hnd := range input {
1086
+		if !hnd.CheckConsistency() {
1087
+			t.Fatalf("Expected corrupted for (%d): %s", idx, hnd)
1088
+		}
1089
+		if hnd.CheckConsistency() {
1090
+			t.Fatalf("Sequence still marked corrupted (%d): %s", idx, hnd)
1091
+		}
1092
+	}
1093
+}
1094
+
1095
+func testSetRollover(t *testing.T, serial bool) {
1096
+	numBlocks := uint32(8)
1097
+	numBits := int(numBlocks * blockLen)
1098
+	hnd := New(uint64(numBits))
1099
+
1100
+	// Allocate first half of the bits
1101
+	for i := 0; i < numBits/2; i++ {
1102
+		_, err := hnd.SetAny(serial)
1103
+		if err != nil {
1104
+			t.Fatalf("Unexpected failure on allocation %d: %v\n%s", i, err, hnd)
1105
+		}
1106
+	}
1107
+
1108
+	if hnd.Unselected() != uint64(numBits/2) {
1109
+		t.Fatalf("Expected full sequence. Instead found %d free bits. %s", hnd.unselected, hnd)
1110
+	}
1111
+
1112
+	seed := time.Now().Unix()
1113
+	rand.Seed(seed)
1114
+
1115
+	// Deallocate half of the allocated bits following a random pattern
1116
+	pattern := rand.Perm(numBits / 2)
1117
+	for i := 0; i < numBits/4; i++ {
1118
+		bit := pattern[i]
1119
+		err := hnd.Unset(uint64(bit))
1120
+		if err != nil {
1121
+			t.Fatalf("Unexpected failure on deallocation of %d: %v.\nSeed: %d.\n%s", bit, err, seed, hnd)
1122
+		}
1123
+	}
1124
+	if hnd.Unselected() != uint64(3*numBits/4) {
1125
+		t.Fatalf("Unexpected free bits: found %d free bits.\nSeed: %d.\n%s", hnd.unselected, seed, hnd)
1126
+	}
1127
+
1128
+	//request to allocate for remaining half of the bits
1129
+	for i := 0; i < numBits/2; i++ {
1130
+		_, err := hnd.SetAny(serial)
1131
+		if err != nil {
1132
+			t.Fatalf("Unexpected failure on allocation %d: %v\nSeed: %d\n%s", i, err, seed, hnd)
1133
+		}
1134
+	}
1135
+
1136
+	//At this point all the bits must be allocated except the randomly unallocated bits
1137
+	//which were unallocated in the first half of the bit sequence
1138
+	if hnd.Unselected() != uint64(numBits/4) {
1139
+		t.Fatalf("Unexpected number of unselected bits %d, Expected %d", hnd.Unselected(), numBits/4)
1140
+	}
1141
+
1142
+	for i := 0; i < numBits/4; i++ {
1143
+		_, err := hnd.SetAny(serial)
1144
+		if err != nil {
1145
+			t.Fatalf("Unexpected failure on allocation %d: %v\nSeed: %d\n%s", i, err, seed, hnd)
1146
+		}
1147
+	}
1148
+	//Now requesting to allocate the unallocated random bits (qurter of the number of bits) should
1149
+	//leave no more bits that can be allocated.
1150
+	if hnd.Unselected() != 0 {
1151
+		t.Fatalf("Unexpected number of unselected bits %d, Expected %d", hnd.Unselected(), 0)
1152
+	}
1153
+}
1154
+
1155
+func TestSetRollover(t *testing.T) {
1156
+	testSetRollover(t, false)
1157
+}
1158
+
1159
+func TestSetRolloverSerial(t *testing.T) {
1160
+	testSetRollover(t, true)
1161
+}
1162
+
1163
+func TestGetFirstAvailableFromCurrent(t *testing.T) {
1164
+	input := []struct {
1165
+		mask    *sequence
1166
+		bytePos uint64
1167
+		bitPos  uint64
1168
+		start   uint64
1169
+		curr    uint64
1170
+		end     uint64
1171
+	}{
1172
+		{&sequence{block: 0xffffffff, count: 2048}, invalidPos, invalidPos, 0, 0, 65536},
1173
+		{&sequence{block: 0x0, count: 8}, 0, 0, 0, 0, 256},
1174
+		{&sequence{block: 0x80000000, count: 8}, 1, 0, 0, 8, 256},
1175
+		{&sequence{block: 0xC0000000, count: 8}, 0, 2, 0, 2, 256},
1176
+		{&sequence{block: 0xE0000000, count: 8}, 0, 3, 0, 0, 256},
1177
+		{&sequence{block: 0xFFFB1FFF, count: 8}, 2, 0, 14, 0, 256},
1178
+		{&sequence{block: 0xFFFFFFFE, count: 8}, 3, 7, 0, 0, 256},
1179
+
1180
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x00000000, count: 1, next: &sequence{block: 0xffffffff, count: 14}}}, 4, 0, 0, 32, 512},
1181
+		{&sequence{block: 0xfffeffff, count: 1, next: &sequence{block: 0xffffffff, count: 15}}, 1, 7, 0, 16, 512},
1182
+		{&sequence{block: 0xfffeffff, count: 15, next: &sequence{block: 0xffffffff, count: 1}}, 5, 7, 0, 16, 512},
1183
+		{&sequence{block: 0xfffeffff, count: 15, next: &sequence{block: 0xffffffff, count: 1}}, 9, 7, 0, 48, 512},
1184
+		{&sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0xffffffef, count: 14}}, 19, 3, 0, 124, 512},
1185
+		{&sequence{block: 0xfffeffff, count: 15, next: &sequence{block: 0x0fffffff, count: 1}}, 60, 0, 0, 480, 512},
1186
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xfffeffff, count: 14, next: &sequence{block: 0xffffffff, count: 1}}}, 17, 7, 0, 124, 512},
1187
+		{&sequence{block: 0xfffffffb, count: 1, next: &sequence{block: 0xffffffff, count: 14, next: &sequence{block: 0xffffffff, count: 1}}}, 3, 5, 0, 124, 512},
1188
+		{&sequence{block: 0xfffffffb, count: 1, next: &sequence{block: 0xfffeffff, count: 14, next: &sequence{block: 0xffffffff, count: 1}}}, 13, 7, 0, 80, 512},
1189
+	}
1190
+
1191
+	for n, i := range input {
1192
+		bytePos, bitPos, _ := getAvailableFromCurrent(i.mask, i.start, i.curr, i.end)
1193
+		if bytePos != i.bytePos || bitPos != i.bitPos {
1194
+			t.Fatalf("Error in (%d) getFirstAvailable(). Expected (%d, %d). Got (%d, %d)", n, i.bytePos, i.bitPos, bytePos, bitPos)
1195
+		}
1196
+	}
1197
+}
1198
+
1199
+func TestMarshalJSON(t *testing.T) {
1200
+	expected := []byte("hello libnetwork")
1201
+	hnd := New(uint64(len(expected) * 8))
1202
+
1203
+	for i, c := range expected {
1204
+		for j := 0; j < 8; j++ {
1205
+			if c&(1<<j) == 0 {
1206
+				continue
1207
+			}
1208
+			if err := hnd.Set(uint64(i*8 + j)); err != nil {
1209
+				t.Fatal(err)
1210
+			}
1211
+		}
1212
+	}
1213
+
1214
+	hstr := hnd.String()
1215
+	t.Log(hstr)
1216
+	marshaled, err := hnd.MarshalJSON()
1217
+	if err != nil {
1218
+		t.Fatalf("MarshalJSON() err = %v", err)
1219
+	}
1220
+	t.Logf("%s", marshaled)
1221
+
1222
+	// Serializations of hnd as would be marshaled by versions of the code
1223
+	// found in the wild. We need to support unmarshaling old versions to
1224
+	// maintain backwards compatibility with sequences persisted on disk.
1225
+	const (
1226
+		goldenV0 = `"AAAAAAAAAIAAAAAAAAAAPRamNjYAAAAAAAAAAfYENpYAAAAAAAAAAUZ2pi4AAAAAAAAAAe72TtYAAAAAAAAAAQ=="`
1227
+	)
1228
+
1229
+	if string(marshaled) != goldenV0 {
1230
+		t.Errorf("MarshalJSON() output differs from golden. Please add a new golden case to this test.")
1231
+	}
1232
+
1233
+	for _, tt := range []struct {
1234
+		name string
1235
+		data []byte
1236
+	}{
1237
+		{name: "Live", data: marshaled},
1238
+		{name: "Golden-v0", data: []byte(goldenV0)},
1239
+	} {
1240
+		tt := tt
1241
+		t.Run("UnmarshalJSON="+tt.name, func(t *testing.T) {
1242
+			hnd2 := New(0)
1243
+			if err := hnd2.UnmarshalJSON(tt.data); err != nil {
1244
+				t.Errorf("UnmarshalJSON() err = %v", err)
1245
+			}
1246
+
1247
+			h2str := hnd2.String()
1248
+			t.Log(h2str)
1249
+			if hstr != h2str {
1250
+				t.Errorf("Unmarshaled a different bitmap: want %q, got %q", hstr, h2str)
1251
+			}
1252
+		})
1253
+	}
1254
+}
... ...
@@ -1,63 +1,44 @@
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.
1
+// Package bitseq provides a structure and utilities for representing a long
2
+// bitmask which is persisted in a datastore. It is backed by [bitmap.Bitmap]
3
+// which operates directly on the encoded representation, without uncompressing.
4 4
 package bitseq
5 5
 
6 6
 import (
7
-	"encoding/binary"
8 7
 	"encoding/json"
9
-	"errors"
10 8
 	"fmt"
11 9
 	"sync"
12 10
 
11
+	"github.com/docker/docker/libnetwork/bitmap"
13 12
 	"github.com/docker/docker/libnetwork/datastore"
14 13
 	"github.com/docker/docker/libnetwork/types"
15 14
 	"github.com/sirupsen/logrus"
16 15
 )
17 16
 
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 17
 var (
29 18
 	// ErrNoBitAvailable is returned when no more bits are available to set
30
-	ErrNoBitAvailable = errors.New("no bit available")
19
+	ErrNoBitAvailable = bitmap.ErrNoBitAvailable
31 20
 	// ErrBitAllocated is returned when the specific bit requested is already set
32
-	ErrBitAllocated = errors.New("requested bit is already allocated")
21
+	ErrBitAllocated = bitmap.ErrBitAllocated
33 22
 )
34 23
 
35 24
 // Handle contains the sequence representing the bitmask and its identifier
36 25
 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
26
+	app      string
27
+	id       string
28
+	dbIndex  uint64
29
+	dbExists bool
30
+	store    datastore.DataStore
31
+	bm       *bitmap.Bitmap
32
+	mu       sync.Mutex
47 33
 }
48 34
 
49 35
 // NewHandle returns a thread-safe instance of the bitmask handler
50 36
 func NewHandle(app string, ds datastore.DataStore, id string, numElements uint64) (*Handle, error) {
51 37
 	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
-		},
38
+		bm:    bitmap.New(numElements),
39
+		app:   app,
40
+		id:    id,
41
+		store: ds,
61 42
 	}
62 43
 
63 44
 	if h.store == nil {
... ...
@@ -79,196 +60,54 @@ func NewHandle(app string, ds datastore.DataStore, id string, numElements uint64
79 79
 	return h, nil
80 80
 }
81 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 82
 func (h *Handle) getCopy() *Handle {
190 83
 	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,
84
+		bm:       bitmap.Copy(h.bm),
85
+		app:      h.app,
86
+		id:       h.id,
87
+		dbIndex:  h.dbIndex,
88
+		dbExists: h.dbExists,
89
+		store:    h.store,
200 90
 	}
201 91
 }
202 92
 
203 93
 // SetAnyInRange atomically sets the first unset bit in the specified range in the sequence and returns the corresponding ordinal
204 94
 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)
95
+	return h.apply(func(b *bitmap.Bitmap) (uint64, error) { return b.SetAnyInRange(start, end, serial) })
212 96
 }
213 97
 
214 98
 // SetAny atomically sets the first unset bit in the sequence and returns the corresponding ordinal
215 99
 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)
100
+	return h.apply(func(b *bitmap.Bitmap) (uint64, error) { return b.SetAny(serial) })
220 101
 }
221 102
 
222 103
 // Set atomically sets the corresponding bit in the sequence
223 104
 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)
105
+	_, err := h.apply(func(b *bitmap.Bitmap) (uint64, error) { return 0, b.Set(ordinal) })
228 106
 	return err
229 107
 }
230 108
 
231 109
 // Unset atomically unsets the corresponding bit in the sequence
232 110
 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)
111
+	_, err := h.apply(func(b *bitmap.Bitmap) (uint64, error) { return 0, b.Unset(ordinal) })
237 112
 	return err
238 113
 }
239 114
 
240 115
 // IsSet atomically checks if the ordinal bit is set. In case ordinal
241 116
 // is outside of the bit sequence limits, false is returned.
242 117
 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
118
+	h.mu.Lock()
119
+	defer h.mu.Unlock()
120
+	return h.bm.IsSet(ordinal)
263 121
 }
264 122
 
265 123
 // CheckConsistency checks if the bit sequence is in an inconsistent state and attempts to fix it.
266 124
 // It looks for a corruption signature that may happen in docker 1.9.0 and 1.9.1.
267 125
 func (h *Handle) CheckConsistency() error {
268 126
 	for {
269
-		h.Lock()
127
+		h.mu.Lock()
270 128
 		store := h.store
271
-		h.Unlock()
129
+		h.mu.Unlock()
272 130
 
273 131
 		if store != nil {
274 132
 			if err := store.GetObject(datastore.Key(h.Key()...), h); err != nil && err != datastore.ErrKeyNotFound {
... ...
@@ -276,11 +115,11 @@ func (h *Handle) CheckConsistency() error {
276 276
 			}
277 277
 		}
278 278
 
279
-		h.Lock()
279
+		h.mu.Lock()
280 280
 		nh := h.getCopy()
281
-		h.Unlock()
281
+		h.mu.Unlock()
282 282
 
283
-		if !nh.runConsistencyCheck() {
283
+		if !nh.bm.CheckConsistency() {
284 284
 			return nil
285 285
 		}
286 286
 
... ...
@@ -293,70 +132,39 @@ func (h *Handle) CheckConsistency() error {
293 293
 
294 294
 		logrus.Infof("Fixed inconsistent bit sequence in datastore:\n%s\n%s", h, nh)
295 295
 
296
-		h.Lock()
297
-		h.head = nh.head
298
-		h.Unlock()
296
+		h.mu.Lock()
297
+		h.bm = nh.bm
298
+		h.mu.Unlock()
299 299
 
300 300
 		return nil
301 301
 	}
302 302
 }
303 303
 
304 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
-
305
+func (h *Handle) apply(op func(*bitmap.Bitmap) (uint64, error)) (uint64, error) {
313 306
 	for {
314 307
 		var store datastore.DataStore
315
-		curr := uint64(0)
316
-		h.Lock()
308
+		h.mu.Lock()
317 309
 		store = h.store
318 310
 		if store != nil {
319
-			h.Unlock() // The lock is acquired in the GetObject
311
+			h.mu.Unlock() // The lock is acquired in the GetObject
320 312
 			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
313
+				return 0, err
341 314
 			}
342
-		}
343
-		if err != nil {
344
-			h.Unlock()
345
-			return ret, err
315
+			h.mu.Lock() // Acquire the lock back
346 316
 		}
347 317
 
348 318
 		// Create a private copy of h and work on it
349 319
 		nh := h.getCopy()
350 320
 
351
-		nh.head = pushReservation(bytePos, bitPos, nh.head, release)
352
-		if release {
353
-			nh.unselected++
354
-		} else {
355
-			nh.unselected--
321
+		ret, err := op(nh.bm)
322
+		if err != nil {
323
+			h.mu.Unlock()
324
+			return ret, err
356 325
 		}
357 326
 
358 327
 		if h.store != nil {
359
-			h.Unlock()
328
+			h.mu.Unlock()
360 329
 			// Attempt to write private copy to store
361 330
 			if err := nh.writeToStore(); err != nil {
362 331
 				if _, ok := err.(types.RetryError); !ok {
... ...
@@ -365,29 +173,18 @@ func (h *Handle) set(ordinal, start, end uint64, any bool, release bool, serial
365 365
 				// Retry
366 366
 				continue
367 367
 			}
368
-			h.Lock()
368
+			h.mu.Lock()
369 369
 		}
370 370
 
371 371
 		// Previous atomic push was successful. Save private copy to local copy
372
-		h.unselected = nh.unselected
373
-		h.head = nh.head
372
+		h.bm = nh.bm
374 373
 		h.dbExists = nh.dbExists
375 374
 		h.dbIndex = nh.dbIndex
376
-		h.Unlock()
375
+		h.mu.Unlock()
377 376
 		return ret, nil
378 377
 	}
379 378
 }
380 379
 
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 380
 // Destroy removes from the datastore the data belonging to this handle
392 381
 func (h *Handle) Destroy() error {
393 382
 	for {
... ...
@@ -408,324 +205,49 @@ func (h *Handle) Destroy() error {
408 408
 	}
409 409
 }
410 410
 
411
-// ToByteArray converts this handle's data into a byte array
412
-func (h *Handle) ToByteArray() ([]byte, error) {
413
-	h.Lock()
414
-	defer h.Unlock()
415
-	ba := make([]byte, 16)
416
-	binary.BigEndian.PutUint64(ba[0:], h.bits)
417
-	binary.BigEndian.PutUint64(ba[8:], h.unselected)
418
-	bm, err := h.head.toByteArray()
419
-	if err != nil {
420
-		return nil, fmt.Errorf("failed to serialize head: %s", err.Error())
421
-	}
422
-	ba = append(ba, bm...)
423
-
424
-	return ba, nil
425
-}
426
-
427
-// FromByteArray reads his handle's data from a byte array
428
-func (h *Handle) FromByteArray(ba []byte) error {
429
-	if ba == nil {
430
-		return errors.New("nil byte array")
431
-	}
432
-
433
-	nh := &sequence{}
434
-	err := nh.fromByteArray(ba[16:])
435
-	if err != nil {
436
-		return fmt.Errorf("failed to deserialize head: %s", err.Error())
437
-	}
438
-
439
-	h.Lock()
440
-	h.head = nh
441
-	h.bits = binary.BigEndian.Uint64(ba[0:8])
442
-	h.unselected = binary.BigEndian.Uint64(ba[8:16])
443
-	h.Unlock()
444
-
445
-	return nil
446
-}
447
-
448 411
 // Bits returns the length of the bit sequence
449 412
 func (h *Handle) Bits() uint64 {
450
-	return h.bits
413
+	h.mu.Lock()
414
+	defer h.mu.Unlock()
415
+	return h.bm.Bits()
451 416
 }
452 417
 
453 418
 // Unselected returns the number of bits which are not selected
454 419
 func (h *Handle) Unselected() uint64 {
455
-	h.Lock()
456
-	defer h.Unlock()
457
-	return h.unselected
420
+	h.mu.Lock()
421
+	defer h.mu.Unlock()
422
+	return h.bm.Unselected()
458 423
 }
459 424
 
460 425
 func (h *Handle) String() string {
461
-	h.Lock()
462
-	defer h.Unlock()
463
-	return fmt.Sprintf("App: %s, ID: %s, DBIndex: 0x%x, Bits: %d, Unselected: %d, Sequence: %s Curr:%d",
464
-		h.app, h.id, h.dbIndex, h.bits, h.unselected, h.head.toString(), h.curr)
426
+	h.mu.Lock()
427
+	defer h.mu.Unlock()
428
+	return fmt.Sprintf("App: %s, ID: %s, DBIndex: 0x%x, %s",
429
+		h.app, h.id, h.dbIndex, h.bm)
465 430
 }
466 431
 
467
-// MarshalJSON encodes Handle into json message
468
-func (h *Handle) MarshalJSON() ([]byte, error) {
469
-	m := map[string]interface{}{
470
-		"id": h.id,
471
-	}
432
+type jsonMessage struct {
433
+	ID       string         `json:"id"`
434
+	Sequence *bitmap.Bitmap `json:"sequence"`
435
+}
472 436
 
473
-	b, err := h.ToByteArray()
474
-	if err != nil {
475
-		return nil, err
476
-	}
477
-	m["sequence"] = b
437
+// MarshalJSON encodes h into a JSON message.
438
+func (h *Handle) MarshalJSON() ([]byte, error) {
439
+	h.mu.Lock()
440
+	defer h.mu.Unlock()
441
+	m := jsonMessage{ID: h.id, Sequence: h.bm}
478 442
 	return json.Marshal(m)
479 443
 }
480 444
 
481
-// UnmarshalJSON decodes json message into Handle
445
+// UnmarshalJSON decodes a JSON message into h.
482 446
 func (h *Handle) UnmarshalJSON(data []byte) error {
483
-	var (
484
-		m   map[string]interface{}
485
-		b   []byte
486
-		err error
487
-	)
488
-	if err = json.Unmarshal(data, &m); err != nil {
489
-		return err
490
-	}
491
-	h.id = m["id"].(string)
492
-	bi, _ := json.Marshal(m["sequence"])
493
-	if err := json.Unmarshal(bi, &b); err != nil {
447
+	var m jsonMessage
448
+	if err := json.Unmarshal(data, &m); err != nil {
494 449
 		return err
495 450
 	}
496
-	return h.FromByteArray(b)
497
-}
498
-
499
-// getFirstAvailable looks for the first unset bit in passed mask starting from start
500
-func getFirstAvailable(head *sequence, start uint64) (uint64, uint64, error) {
501
-	// Find sequence which contains the start bit
502
-	byteStart, bitStart := ordinalToPos(start)
503
-	current, _, precBlocks, inBlockBytePos := findSequence(head, byteStart)
504
-	// Derive the this sequence offsets
505
-	byteOffset := byteStart - inBlockBytePos
506
-	bitOffset := inBlockBytePos*8 + bitStart
507
-	for current != nil {
508
-		if current.block != blockMAX {
509
-			// If the current block is not full, check if there is any bit
510
-			// from the current bit in the current block. If not, before proceeding to the
511
-			// next block node, make sure we check for available bit in the next
512
-			// instance of the same block. Due to RLE same block signature will be
513
-			// compressed.
514
-		retry:
515
-			bytePos, bitPos, err := current.getAvailableBit(bitOffset)
516
-			if err != nil && precBlocks == current.count-1 {
517
-				// This is the last instance in the same block node,
518
-				// so move to the next block.
519
-				goto next
520
-			}
521
-			if err != nil {
522
-				// There are some more instances of the same block, so add the offset
523
-				// and be optimistic that you will find the available bit in the next
524
-				// instance of the same block.
525
-				bitOffset = 0
526
-				byteOffset += blockBytes
527
-				precBlocks++
528
-				goto retry
529
-			}
530
-			return byteOffset + bytePos, bitPos, err
531
-		}
532
-		// Moving to next block: Reset bit offset.
533
-	next:
534
-		bitOffset = 0
535
-		byteOffset += (current.count * blockBytes) - (precBlocks * blockBytes)
536
-		precBlocks = 0
537
-		current = current.next
538
-	}
539
-	return invalidPos, invalidPos, ErrNoBitAvailable
540
-}
541
-
542
-// getAvailableFromCurrent will look for available ordinal from the current ordinal.
543
-// If none found then it will loop back to the start to check of the available bit.
544
-// This can be further optimized to check from start till curr in case of a rollover
545
-func getAvailableFromCurrent(head *sequence, start, curr, end uint64) (uint64, uint64, error) {
546
-	var bytePos, bitPos uint64
547
-	var err error
548
-	if curr != 0 && curr > start {
549
-		bytePos, bitPos, err = getFirstAvailable(head, curr)
550
-		ret := posToOrdinal(bytePos, bitPos)
551
-		if end < ret || err != nil {
552
-			goto begin
553
-		}
554
-		return bytePos, bitPos, nil
555
-	}
556
-
557
-begin:
558
-	bytePos, bitPos, err = getFirstAvailable(head, start)
559
-	ret := posToOrdinal(bytePos, bitPos)
560
-	if end < ret || err != nil {
561
-		return invalidPos, invalidPos, ErrNoBitAvailable
562
-	}
563
-	return bytePos, bitPos, nil
564
-}
565
-
566
-// checkIfAvailable checks if the bit correspondent to the specified ordinal is unset
567
-// If the ordinal is beyond the sequence limits, a negative response is returned
568
-func checkIfAvailable(head *sequence, ordinal uint64) (uint64, uint64, error) {
569
-	bytePos, bitPos := ordinalToPos(ordinal)
570
-
571
-	// Find the sequence containing this byte
572
-	current, _, _, inBlockBytePos := findSequence(head, bytePos)
573
-	if current != nil {
574
-		// Check whether the bit corresponding to the ordinal address is unset
575
-		bitSel := blockFirstBit >> (inBlockBytePos*8 + bitPos)
576
-		if current.block&bitSel == 0 {
577
-			return bytePos, bitPos, nil
578
-		}
579
-	}
580
-
581
-	return invalidPos, invalidPos, ErrBitAllocated
582
-}
583
-
584
-// Given the byte position and the sequences list head, return the pointer to the
585
-// sequence containing the byte (current), the pointer to the previous sequence,
586
-// the number of blocks preceding the block containing the byte inside the current sequence.
587
-// If bytePos is outside of the list, function will return (nil, nil, 0, invalidPos)
588
-func findSequence(head *sequence, bytePos uint64) (*sequence, *sequence, uint64, uint64) {
589
-	// Find the sequence containing this byte
590
-	previous := head
591
-	current := head
592
-	n := bytePos
593
-	for current.next != nil && n >= (current.count*blockBytes) { // Nil check for less than 32 addresses masks
594
-		n -= (current.count * blockBytes)
595
-		previous = current
596
-		current = current.next
597
-	}
598 451
 
599
-	// If byte is outside of the list, let caller know
600
-	if n >= (current.count * blockBytes) {
601
-		return nil, nil, 0, invalidPos
602
-	}
603
-
604
-	// Find the byte position inside the block and the number of blocks
605
-	// preceding the block containing the byte inside this sequence
606
-	precBlocks := n / blockBytes
607
-	inBlockBytePos := bytePos % blockBytes
608
-
609
-	return current, previous, precBlocks, inBlockBytePos
610
-}
611
-
612
-// PushReservation pushes the bit reservation inside the bitmask.
613
-// Given byte and bit positions, identify the sequence (current) which holds the block containing the affected bit.
614
-// Create a new block with the modified bit according to the operation (allocate/release).
615
-// Create a new sequence containing the new block and insert it in the proper position.
616
-// Remove current sequence if empty.
617
-// Check if new sequence can be merged with neighbour (previous/next) sequences.
618
-//
619
-// Identify "current" sequence containing block:
620
-//
621
-//	[prev seq] [current seq] [next seq]
622
-//
623
-// Based on block position, resulting list of sequences can be any of three forms:
624
-//
625
-// block position                        Resulting list of sequences
626
-//
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
452
+	h.mu.Lock()
453
+	defer h.mu.Unlock()
454
+	h.id, h.bm = m.ID, m.Sequence
455
+	return nil
731 456
 }
... ...
@@ -41,754 +41,7 @@ func randomLocalStore() (datastore.DataStore, error) {
41 41
 	})
42 42
 }
43 43
 
44
-func TestSequenceGetAvailableBit(t *testing.T) {
45
-	input := []struct {
46
-		head    *sequence
47
-		from    uint64
48
-		bytePos uint64
49
-		bitPos  uint64
50
-	}{
51
-		{&sequence{block: 0x0, count: 0}, 0, invalidPos, invalidPos},
52
-		{&sequence{block: 0x0, count: 1}, 0, 0, 0},
53
-		{&sequence{block: 0x0, count: 100}, 0, 0, 0},
54
-
55
-		{&sequence{block: 0x80000000, count: 0}, 0, invalidPos, invalidPos},
56
-		{&sequence{block: 0x80000000, count: 1}, 0, 0, 1},
57
-		{&sequence{block: 0x80000000, count: 100}, 0, 0, 1},
58
-
59
-		{&sequence{block: 0xFF000000, count: 0}, 0, invalidPos, invalidPos},
60
-		{&sequence{block: 0xFF000000, count: 1}, 0, 1, 0},
61
-		{&sequence{block: 0xFF000000, count: 100}, 0, 1, 0},
62
-
63
-		{&sequence{block: 0xFF800000, count: 0}, 0, invalidPos, invalidPos},
64
-		{&sequence{block: 0xFF800000, count: 1}, 0, 1, 1},
65
-		{&sequence{block: 0xFF800000, count: 100}, 0, 1, 1},
66
-
67
-		{&sequence{block: 0xFFC0FF00, count: 0}, 0, invalidPos, invalidPos},
68
-		{&sequence{block: 0xFFC0FF00, count: 1}, 0, 1, 2},
69
-		{&sequence{block: 0xFFC0FF00, count: 100}, 0, 1, 2},
70
-
71
-		{&sequence{block: 0xFFE0FF00, count: 0}, 0, invalidPos, invalidPos},
72
-		{&sequence{block: 0xFFE0FF00, count: 1}, 0, 1, 3},
73
-		{&sequence{block: 0xFFE0FF00, count: 100}, 0, 1, 3},
74
-
75
-		{&sequence{block: 0xFFFEFF00, count: 0}, 0, invalidPos, invalidPos},
76
-		{&sequence{block: 0xFFFEFF00, count: 1}, 0, 1, 7},
77
-		{&sequence{block: 0xFFFEFF00, count: 100}, 0, 1, 7},
78
-
79
-		{&sequence{block: 0xFFFFC0FF, count: 0}, 0, invalidPos, invalidPos},
80
-		{&sequence{block: 0xFFFFC0FF, count: 1}, 0, 2, 2},
81
-		{&sequence{block: 0xFFFFC0FF, count: 100}, 0, 2, 2},
82
-
83
-		{&sequence{block: 0xFFFFFF00, count: 0}, 0, invalidPos, invalidPos},
84
-		{&sequence{block: 0xFFFFFF00, count: 1}, 0, 3, 0},
85
-		{&sequence{block: 0xFFFFFF00, count: 100}, 0, 3, 0},
86
-
87
-		{&sequence{block: 0xFFFFFFFE, count: 0}, 0, invalidPos, invalidPos},
88
-		{&sequence{block: 0xFFFFFFFE, count: 1}, 0, 3, 7},
89
-		{&sequence{block: 0xFFFFFFFE, count: 100}, 0, 3, 7},
90
-
91
-		{&sequence{block: 0xFFFFFFFF, count: 0}, 0, invalidPos, invalidPos},
92
-		{&sequence{block: 0xFFFFFFFF, count: 1}, 0, invalidPos, invalidPos},
93
-		{&sequence{block: 0xFFFFFFFF, count: 100}, 0, invalidPos, invalidPos},
94
-
95
-		// now test with offset
96
-		{&sequence{block: 0x0, count: 0}, 0, invalidPos, invalidPos},
97
-		{&sequence{block: 0x0, count: 0}, 31, invalidPos, invalidPos},
98
-		{&sequence{block: 0x0, count: 0}, 32, invalidPos, invalidPos},
99
-		{&sequence{block: 0x0, count: 1}, 0, 0, 0},
100
-		{&sequence{block: 0x0, count: 1}, 1, 0, 1},
101
-		{&sequence{block: 0x0, count: 1}, 31, 3, 7},
102
-		{&sequence{block: 0xF0FF0000, count: 1}, 0, 0, 4},
103
-		{&sequence{block: 0xF0FF0000, count: 1}, 8, 2, 0},
104
-		{&sequence{block: 0xFFFFFFFF, count: 1}, 0, invalidPos, invalidPos},
105
-		{&sequence{block: 0xFFFFFFFF, count: 1}, 16, invalidPos, invalidPos},
106
-		{&sequence{block: 0xFFFFFFFF, count: 1}, 31, invalidPos, invalidPos},
107
-		{&sequence{block: 0xFFFFFFFE, count: 1}, 0, 3, 7},
108
-		{&sequence{block: 0xFFFFFFFF, count: 2}, 0, invalidPos, invalidPos},
109
-		{&sequence{block: 0xFFFFFFFF, count: 2}, 32, invalidPos, invalidPos},
110
-	}
111
-
112
-	for n, i := range input {
113
-		b, bb, err := i.head.getAvailableBit(i.from)
114
-		if b != i.bytePos || bb != i.bitPos {
115
-			t.Fatalf("Error in sequence.getAvailableBit(%d) (%d).\nExp: (%d, %d)\nGot: (%d, %d), err: %v", i.from, n, i.bytePos, i.bitPos, b, bb, err)
116
-		}
117
-	}
118
-}
119
-
120
-func TestSequenceEqual(t *testing.T) {
121
-	input := []struct {
122
-		first    *sequence
123
-		second   *sequence
124
-		areEqual bool
125
-	}{
126
-		{&sequence{block: 0x0, count: 8, next: nil}, &sequence{block: 0x0, count: 8}, true},
127
-		{&sequence{block: 0x0, count: 0, next: nil}, &sequence{block: 0x0, count: 0}, true},
128
-		{&sequence{block: 0x0, count: 2, next: nil}, &sequence{block: 0x0, count: 1, next: &sequence{block: 0x0, count: 1}}, false},
129
-		{&sequence{block: 0x0, count: 2, next: &sequence{block: 0x1, count: 1}}, &sequence{block: 0x0, count: 2}, false},
130
-
131
-		{&sequence{block: 0x12345678, count: 8, next: nil}, &sequence{block: 0x12345678, count: 8}, true},
132
-		{&sequence{block: 0x12345678, count: 8, next: nil}, &sequence{block: 0x12345678, count: 9}, false},
133
-		{&sequence{block: 0x12345678, count: 1, next: &sequence{block: 0xFFFFFFFF, count: 1}}, &sequence{block: 0x12345678, count: 1}, false},
134
-		{&sequence{block: 0x12345678, count: 1}, &sequence{block: 0x12345678, count: 1, next: &sequence{block: 0xFFFFFFFF, count: 1}}, false},
135
-	}
136
-
137
-	for n, i := range input {
138
-		if i.areEqual != i.first.equal(i.second) {
139
-			t.Fatalf("Error in sequence.equal() (%d).\nExp: %t\nGot: %t,", n, i.areEqual, !i.areEqual)
140
-		}
141
-	}
142
-}
143
-
144
-func TestSequenceCopy(t *testing.T) {
145
-	s := getTestSequence()
146
-	n := s.getCopy()
147
-	if !s.equal(n) {
148
-		t.Fatal("copy of s failed")
149
-	}
150
-	if n == s {
151
-		t.Fatal("not true copy of s")
152
-	}
153
-}
154
-
155
-func TestGetFirstAvailable(t *testing.T) {
156
-	input := []struct {
157
-		mask    *sequence
158
-		bytePos uint64
159
-		bitPos  uint64
160
-		start   uint64
161
-	}{
162
-		{&sequence{block: 0xffffffff, count: 2048}, invalidPos, invalidPos, 0},
163
-		{&sequence{block: 0x0, count: 8}, 0, 0, 0},
164
-		{&sequence{block: 0x80000000, count: 8}, 0, 1, 0},
165
-		{&sequence{block: 0xC0000000, count: 8}, 0, 2, 0},
166
-		{&sequence{block: 0xE0000000, count: 8}, 0, 3, 0},
167
-		{&sequence{block: 0xF0000000, count: 8}, 0, 4, 0},
168
-		{&sequence{block: 0xF8000000, count: 8}, 0, 5, 0},
169
-		{&sequence{block: 0xFC000000, count: 8}, 0, 6, 0},
170
-		{&sequence{block: 0xFE000000, count: 8}, 0, 7, 0},
171
-		{&sequence{block: 0xFE000000, count: 8}, 3, 0, 24},
172
-
173
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x00000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 0, 0},
174
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 1, 0},
175
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 2, 0},
176
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xE0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 3, 0},
177
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 4, 0},
178
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF8000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 5, 0},
179
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFC000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 6, 0},
180
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFE000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 7, 0},
181
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x0E000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 0, 16},
182
-
183
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 0, 0},
184
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF800000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 1, 0},
185
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFC00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 2, 0},
186
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFE00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 3, 0},
187
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 4, 0},
188
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF80000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 5, 0},
189
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFC0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 6, 0},
190
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFE0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 7, 0},
191
-
192
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 7, 7, 0},
193
-
194
-		{&sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0x0, count: 6}}, 8, 0, 0},
195
-		{&sequence{block: 0xfffcffff, count: 1, next: &sequence{block: 0x0, count: 6}}, 4, 0, 16},
196
-		{&sequence{block: 0xfffcffff, count: 1, next: &sequence{block: 0x0, count: 6}}, 1, 7, 15},
197
-		{&sequence{block: 0xfffcffff, count: 1, next: &sequence{block: 0x0, count: 6}}, 1, 6, 10},
198
-		{&sequence{block: 0xfffcfffe, count: 1, next: &sequence{block: 0x0, count: 6}}, 3, 7, 31},
199
-		{&sequence{block: 0xfffcffff, count: 1, next: &sequence{block: 0xffffffff, count: 6}}, invalidPos, invalidPos, 31},
200
-	}
201
-
202
-	for n, i := range input {
203
-		bytePos, bitPos, _ := getFirstAvailable(i.mask, i.start)
204
-		if bytePos != i.bytePos || bitPos != i.bitPos {
205
-			t.Fatalf("Error in (%d) getFirstAvailable(). Expected (%d, %d). Got (%d, %d)", n, i.bytePos, i.bitPos, bytePos, bitPos)
206
-		}
207
-	}
208
-}
209
-
210
-func TestFindSequence(t *testing.T) {
211
-	input := []struct {
212
-		head           *sequence
213
-		bytePos        uint64
214
-		precBlocks     uint64
215
-		inBlockBytePos uint64
216
-	}{
217
-		{&sequence{block: 0xffffffff, count: 0}, 0, 0, invalidPos},
218
-		{&sequence{block: 0xffffffff, count: 0}, 31, 0, invalidPos},
219
-		{&sequence{block: 0xffffffff, count: 0}, 100, 0, invalidPos},
220
-
221
-		{&sequence{block: 0x0, count: 1}, 0, 0, 0},
222
-		{&sequence{block: 0x0, count: 1}, 1, 0, 1},
223
-		{&sequence{block: 0x0, count: 1}, 31, 0, invalidPos},
224
-		{&sequence{block: 0x0, count: 1}, 60, 0, invalidPos},
225
-
226
-		{&sequence{block: 0xffffffff, count: 10}, 0, 0, 0},
227
-		{&sequence{block: 0xffffffff, count: 10}, 3, 0, 3},
228
-		{&sequence{block: 0xffffffff, count: 10}, 4, 1, 0},
229
-		{&sequence{block: 0xffffffff, count: 10}, 7, 1, 3},
230
-		{&sequence{block: 0xffffffff, count: 10}, 8, 2, 0},
231
-		{&sequence{block: 0xffffffff, count: 10}, 39, 9, 3},
232
-
233
-		{&sequence{block: 0xffffffff, count: 10, next: &sequence{block: 0xcc000000, count: 10}}, 79, 9, 3},
234
-		{&sequence{block: 0xffffffff, count: 10, next: &sequence{block: 0xcc000000, count: 10}}, 80, 0, invalidPos},
235
-	}
236
-
237
-	for n, i := range input {
238
-		_, _, precBlocks, inBlockBytePos := findSequence(i.head, i.bytePos)
239
-		if precBlocks != i.precBlocks || inBlockBytePos != i.inBlockBytePos {
240
-			t.Fatalf("Error in (%d) findSequence(). Expected (%d, %d). Got (%d, %d)", n, i.precBlocks, i.inBlockBytePos, precBlocks, inBlockBytePos)
241
-		}
242
-	}
243
-}
244
-
245
-func TestCheckIfAvailable(t *testing.T) {
246
-	input := []struct {
247
-		head    *sequence
248
-		ordinal uint64
249
-		bytePos uint64
250
-		bitPos  uint64
251
-	}{
252
-		{&sequence{block: 0xffffffff, count: 0}, 0, invalidPos, invalidPos},
253
-		{&sequence{block: 0xffffffff, count: 0}, 31, invalidPos, invalidPos},
254
-		{&sequence{block: 0xffffffff, count: 0}, 100, invalidPos, invalidPos},
255
-
256
-		{&sequence{block: 0x0, count: 1}, 0, 0, 0},
257
-		{&sequence{block: 0x0, count: 1}, 1, 0, 1},
258
-		{&sequence{block: 0x0, count: 1}, 31, 3, 7},
259
-		{&sequence{block: 0x0, count: 1}, 60, invalidPos, invalidPos},
260
-
261
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x800000ff, count: 1}}, 31, invalidPos, invalidPos},
262
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x800000ff, count: 1}}, 32, invalidPos, invalidPos},
263
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x800000ff, count: 1}}, 33, 4, 1},
264
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1}}, 33, invalidPos, invalidPos},
265
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1}}, 34, 4, 2},
266
-
267
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1, next: &sequence{block: 0x0, count: 1}}}, 55, 6, 7},
268
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1, next: &sequence{block: 0x0, count: 1}}}, 56, invalidPos, invalidPos},
269
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1, next: &sequence{block: 0x0, count: 1}}}, 63, invalidPos, invalidPos},
270
-
271
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1, next: &sequence{block: 0x0, count: 1}}}, 64, 8, 0},
272
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1, next: &sequence{block: 0x0, count: 1}}}, 95, 11, 7},
273
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1, next: &sequence{block: 0x0, count: 1}}}, 96, invalidPos, invalidPos},
274
-	}
275
-
276
-	for n, i := range input {
277
-		bytePos, bitPos, err := checkIfAvailable(i.head, i.ordinal)
278
-		if bytePos != i.bytePos || bitPos != i.bitPos {
279
-			t.Fatalf("Error in (%d) checkIfAvailable(ord:%d). Expected (%d, %d). Got (%d, %d). err: %v", n, i.ordinal, i.bytePos, i.bitPos, bytePos, bitPos, err)
280
-		}
281
-	}
282
-}
283
-
284
-func TestMergeSequences(t *testing.T) {
285
-	input := []struct {
286
-		original *sequence
287
-		merged   *sequence
288
-	}{
289
-		{&sequence{block: 0xFE000000, count: 8, next: &sequence{block: 0xFE000000, count: 2}}, &sequence{block: 0xFE000000, count: 10}},
290
-		{&sequence{block: 0xFFFFFFFF, count: 8, next: &sequence{block: 0xFFFFFFFF, count: 1}}, &sequence{block: 0xFFFFFFFF, count: 9}},
291
-		{&sequence{block: 0xFFFFFFFF, count: 1, next: &sequence{block: 0xFFFFFFFF, count: 8}}, &sequence{block: 0xFFFFFFFF, count: 9}},
292
-
293
-		{&sequence{block: 0xFFFFFFF0, count: 8, next: &sequence{block: 0xFFFFFFF0, count: 1}}, &sequence{block: 0xFFFFFFF0, count: 9}},
294
-		{&sequence{block: 0xFFFFFFF0, count: 1, next: &sequence{block: 0xFFFFFFF0, count: 8}}, &sequence{block: 0xFFFFFFF0, count: 9}},
295
-
296
-		{&sequence{block: 0xFE, count: 8, next: &sequence{block: 0xFE, count: 1, next: &sequence{block: 0xFE, count: 5}}}, &sequence{block: 0xFE, count: 14}},
297
-		{&sequence{block: 0xFE, count: 8, next: &sequence{block: 0xFE, count: 1, next: &sequence{block: 0xFE, count: 5, next: &sequence{block: 0xFF, count: 1}}}},
298
-			&sequence{block: 0xFE, count: 14, next: &sequence{block: 0xFF, count: 1}}},
299
-
300
-		// No merge
301
-		{&sequence{block: 0xFE, count: 8, next: &sequence{block: 0xF8, count: 1, next: &sequence{block: 0xFE, count: 5}}},
302
-			&sequence{block: 0xFE, count: 8, next: &sequence{block: 0xF8, count: 1, next: &sequence{block: 0xFE, count: 5}}}},
303
-
304
-		// No merge from head: // Merge function tries to merge from passed head. If it can't merge with next, it does not reattempt with next as head
305
-		{&sequence{block: 0xFE, count: 8, next: &sequence{block: 0xFF, count: 1, next: &sequence{block: 0xFF, count: 5}}},
306
-			&sequence{block: 0xFE, count: 8, next: &sequence{block: 0xFF, count: 6}}},
307
-	}
308
-
309
-	for n, i := range input {
310
-		mergeSequences(i.original)
311
-		for !i.merged.equal(i.original) {
312
-			t.Fatalf("Error in (%d) mergeSequences().\nExp: %s\nGot: %s,", n, i.merged.toString(), i.original.toString())
313
-		}
314
-	}
315
-}
316
-
317
-func TestPushReservation(t *testing.T) {
318
-	input := []struct {
319
-		mask    *sequence
320
-		bytePos uint64
321
-		bitPos  uint64
322
-		newMask *sequence
323
-	}{
324
-		// Create first sequence and fill in 8 addresses starting from address 0
325
-		{&sequence{block: 0x0, count: 8, next: nil}, 0, 0, &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 7, next: nil}}},
326
-		{&sequence{block: 0x80000000, count: 8}, 0, 1, &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0x80000000, count: 7, next: nil}}},
327
-		{&sequence{block: 0xC0000000, count: 8}, 0, 2, &sequence{block: 0xE0000000, count: 1, next: &sequence{block: 0xC0000000, count: 7, next: nil}}},
328
-		{&sequence{block: 0xE0000000, count: 8}, 0, 3, &sequence{block: 0xF0000000, count: 1, next: &sequence{block: 0xE0000000, count: 7, next: nil}}},
329
-		{&sequence{block: 0xF0000000, count: 8}, 0, 4, &sequence{block: 0xF8000000, count: 1, next: &sequence{block: 0xF0000000, count: 7, next: nil}}},
330
-		{&sequence{block: 0xF8000000, count: 8}, 0, 5, &sequence{block: 0xFC000000, count: 1, next: &sequence{block: 0xF8000000, count: 7, next: nil}}},
331
-		{&sequence{block: 0xFC000000, count: 8}, 0, 6, &sequence{block: 0xFE000000, count: 1, next: &sequence{block: 0xFC000000, count: 7, next: nil}}},
332
-		{&sequence{block: 0xFE000000, count: 8}, 0, 7, &sequence{block: 0xFF000000, count: 1, next: &sequence{block: 0xFE000000, count: 7, next: nil}}},
333
-
334
-		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 7}}, 0, 1, &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0x0, count: 7, next: nil}}},
335
-
336
-		// Create second sequence and fill in 8 addresses starting from address 32
337
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x00000000, count: 1, next: &sequence{block: 0xffffffff, count: 6, next: nil}}}, 4, 0,
338
-			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
339
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 1,
340
-			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
341
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 2,
342
-			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xE0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
343
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xE0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 3,
344
-			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
345
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 4,
346
-			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF8000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
347
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF8000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 5,
348
-			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFC000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
349
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFC000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 6,
350
-			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFE000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
351
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFE000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 7,
352
-			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
353
-		// fill in 8 addresses starting from address 40
354
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 0,
355
-			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF800000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
356
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF800000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 1,
357
-			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFC00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
358
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFC00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 2,
359
-			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFE00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
360
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFE00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 3,
361
-			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
362
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 4,
363
-			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF80000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
364
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF80000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 5,
365
-			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFC0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
366
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFC0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 6,
367
-			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFE0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
368
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFE0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 7,
369
-			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFF0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
370
-
371
-		// Insert new sequence
372
-		{&sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0x0, count: 6}}, 8, 0,
373
-			&sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5}}}},
374
-		{&sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5}}}, 8, 1,
375
-			&sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0x0, count: 5}}}},
376
-
377
-		// Merge affected with next
378
-		{&sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 2, next: &sequence{block: 0xffffffff, count: 1}}}, 31, 7,
379
-			&sequence{block: 0xffffffff, count: 8, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 1}}}},
380
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xfffffffc, count: 1, next: &sequence{block: 0xfffffffe, count: 6}}}, 7, 6,
381
-			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xfffffffe, count: 7}}},
382
-
383
-		// Merge affected with next and next.next
384
-		{&sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 1}}}, 31, 7,
385
-			&sequence{block: 0xffffffff, count: 9}},
386
-		{&sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 1}}, 31, 7,
387
-			&sequence{block: 0xffffffff, count: 8}},
388
-
389
-		// Merge affected with previous and next
390
-		{&sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 1}}}, 31, 7,
391
-			&sequence{block: 0xffffffff, count: 9}},
392
-
393
-		// Redundant push: No change
394
-		{&sequence{block: 0xffff0000, count: 1}, 0, 0, &sequence{block: 0xffff0000, count: 1}},
395
-		{&sequence{block: 0xffff0000, count: 7}, 25, 7, &sequence{block: 0xffff0000, count: 7}},
396
-		{&sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 1}}}, 7, 7,
397
-			&sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 1}}}},
398
-
399
-		// Set last bit
400
-		{&sequence{block: 0x0, count: 8}, 31, 7, &sequence{block: 0x0, count: 7, next: &sequence{block: 0x1, count: 1}}},
401
-
402
-		// Set bit in a middle sequence in the first block, first bit
403
-		{&sequence{block: 0x40000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 4, 0,
404
-			&sequence{block: 0x40000000, count: 1, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5,
405
-				next: &sequence{block: 0x1, count: 1}}}}},
406
-
407
-		// Set bit in a middle sequence in the first block, first bit (merge involved)
408
-		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 4, 0,
409
-			&sequence{block: 0x80000000, count: 2, next: &sequence{block: 0x0, count: 5, next: &sequence{block: 0x1, count: 1}}}},
410
-
411
-		// Set bit in a middle sequence in the first block, last bit
412
-		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 4, 31,
413
-			&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x1, count: 1, next: &sequence{block: 0x0, count: 5,
414
-				next: &sequence{block: 0x1, count: 1}}}}},
415
-
416
-		// Set bit in a middle sequence in the first block, middle bit
417
-		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 4, 16,
418
-			&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x8000, count: 1, next: &sequence{block: 0x0, count: 5,
419
-				next: &sequence{block: 0x1, count: 1}}}}},
420
-
421
-		// Set bit in a middle sequence in a middle block, first bit
422
-		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 16, 0,
423
-			&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 3, next: &sequence{block: 0x80000000, count: 1,
424
-				next: &sequence{block: 0x0, count: 2, next: &sequence{block: 0x1, count: 1}}}}}},
425
-
426
-		// Set bit in a middle sequence in a middle block, last bit
427
-		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 16, 31,
428
-			&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 3, next: &sequence{block: 0x1, count: 1,
429
-				next: &sequence{block: 0x0, count: 2, next: &sequence{block: 0x1, count: 1}}}}}},
430
-
431
-		// Set bit in a middle sequence in a middle block, middle bit
432
-		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 16, 15,
433
-			&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 3, next: &sequence{block: 0x10000, count: 1,
434
-				next: &sequence{block: 0x0, count: 2, next: &sequence{block: 0x1, count: 1}}}}}},
435
-
436
-		// Set bit in a middle sequence in the last block, first bit
437
-		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 24, 0,
438
-			&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5, next: &sequence{block: 0x80000000, count: 1,
439
-				next: &sequence{block: 0x1, count: 1}}}}},
440
-
441
-		// Set bit in a middle sequence in the last block, last bit
442
-		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x4, count: 1}}}, 24, 31,
443
-			&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5, next: &sequence{block: 0x1, count: 1,
444
-				next: &sequence{block: 0x4, count: 1}}}}},
445
-
446
-		// Set bit in a middle sequence in the last block, last bit (merge involved)
447
-		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 24, 31,
448
-			&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5, next: &sequence{block: 0x1, count: 2}}}},
449
-
450
-		// Set bit in a middle sequence in the last block, middle bit
451
-		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 24, 16,
452
-			&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5, next: &sequence{block: 0x8000, count: 1,
453
-				next: &sequence{block: 0x1, count: 1}}}}},
454
-	}
455
-
456
-	for n, i := range input {
457
-		mask := pushReservation(i.bytePos, i.bitPos, i.mask, false)
458
-		if !mask.equal(i.newMask) {
459
-			t.Fatalf("Error in (%d) pushReservation():\n%s + (%d,%d):\nExp: %s\nGot: %s,",
460
-				n, i.mask.toString(), i.bytePos, i.bitPos, i.newMask.toString(), mask.toString())
461
-		}
462
-	}
463
-}
464
-
465
-func TestSerializeDeserialize(t *testing.T) {
466
-	s := getTestSequence()
467
-
468
-	data, err := s.toByteArray()
469
-	if err != nil {
470
-		t.Fatal(err)
471
-	}
472
-
473
-	r := &sequence{}
474
-	err = r.fromByteArray(data)
475
-	if err != nil {
476
-		t.Fatal(err)
477
-	}
478
-
479
-	if !s.equal(r) {
480
-		t.Fatalf("Sequences are different: \n%v\n%v", s, r)
481
-	}
482
-}
483
-
484
-func getTestSequence() *sequence {
485
-	// Returns a custom sequence of 1024 * 32 bits
486
-	return &sequence{
487
-		block: 0xFFFFFFFF,
488
-		count: 100,
489
-		next: &sequence{
490
-			block: 0xFFFFFFFE,
491
-			count: 1,
492
-			next: &sequence{
493
-				block: 0xFF000000,
494
-				count: 10,
495
-				next: &sequence{
496
-					block: 0xFFFFFFFF,
497
-					count: 50,
498
-					next: &sequence{
499
-						block: 0xFFFFFFFC,
500
-						count: 1,
501
-						next: &sequence{
502
-							block: 0xFF800000,
503
-							count: 1,
504
-							next: &sequence{
505
-								block: 0xFFFFFFFF,
506
-								count: 87,
507
-								next: &sequence{
508
-									block: 0x0,
509
-									count: 150,
510
-									next: &sequence{
511
-										block: 0xFFFFFFFF,
512
-										count: 200,
513
-										next: &sequence{
514
-											block: 0x0000FFFF,
515
-											count: 1,
516
-											next: &sequence{
517
-												block: 0x0,
518
-												count: 399,
519
-												next: &sequence{
520
-													block: 0xFFFFFFFF,
521
-													count: 23,
522
-													next: &sequence{
523
-														block: 0x1,
524
-														count: 1,
525
-													},
526
-												},
527
-											},
528
-										},
529
-									},
530
-								},
531
-							},
532
-						},
533
-					},
534
-				},
535
-			},
536
-		},
537
-	}
538
-}
539
-
540
-func TestSet(t *testing.T) {
541
-	hnd, err := NewHandle("", nil, "", 1024*32)
542
-	if err != nil {
543
-		t.Fatal(err)
544
-	}
545
-	hnd.head = getTestSequence()
546
-
547
-	firstAv := uint64(32*100 + 31)
548
-	last := uint64(1024*32 - 1)
549
-
550
-	if hnd.IsSet(100000) {
551
-		t.Fatal("IsSet() returned wrong result")
552
-	}
553
-
554
-	if !hnd.IsSet(0) {
555
-		t.Fatal("IsSet() returned wrong result")
556
-	}
557
-
558
-	if hnd.IsSet(firstAv) {
559
-		t.Fatal("IsSet() returned wrong result")
560
-	}
561
-
562
-	if !hnd.IsSet(last) {
563
-		t.Fatal("IsSet() returned wrong result")
564
-	}
565
-
566
-	if err := hnd.Set(0); err == nil {
567
-		t.Fatal("Expected failure, but succeeded")
568
-	}
569
-
570
-	os, err := hnd.SetAny(false)
571
-	if err != nil {
572
-		t.Fatalf("Unexpected failure: %v", err)
573
-	}
574
-	if os != firstAv {
575
-		t.Fatalf("SetAny returned unexpected ordinal. Expected %d. Got %d.", firstAv, os)
576
-	}
577
-	if !hnd.IsSet(firstAv) {
578
-		t.Fatal("IsSet() returned wrong result")
579
-	}
580
-
581
-	if err := hnd.Unset(firstAv); err != nil {
582
-		t.Fatalf("Unexpected failure: %v", err)
583
-	}
584
-
585
-	if hnd.IsSet(firstAv) {
586
-		t.Fatal("IsSet() returned wrong result")
587
-	}
588
-
589
-	if err := hnd.Set(firstAv); err != nil {
590
-		t.Fatalf("Unexpected failure: %v", err)
591
-	}
592
-
593
-	if err := hnd.Set(last); err == nil {
594
-		t.Fatal("Expected failure, but succeeded")
595
-	}
596
-}
597
-
598
-func TestSetUnset(t *testing.T) {
599
-	numBits := uint64(32 * blockLen)
600
-	hnd, err := NewHandle("", nil, "", numBits)
601
-	if err != nil {
602
-		t.Fatal(err)
603
-	}
604
-
605
-	if err := hnd.Set(uint64(32 * blockLen)); err == nil {
606
-		t.Fatal("Expected failure, but succeeded")
607
-	}
608
-	if err := hnd.Unset(uint64(32 * blockLen)); err == nil {
609
-		t.Fatal("Expected failure, but succeeded")
610
-	}
611
-
612
-	// set and unset all one by one
613
-	for hnd.Unselected() > 0 {
614
-		if _, err := hnd.SetAny(false); err != nil {
615
-			t.Fatal(err)
616
-		}
617
-	}
618
-	if _, err := hnd.SetAny(false); err != ErrNoBitAvailable {
619
-		t.Fatal("Expected error. Got success")
620
-	}
621
-	if _, err := hnd.SetAnyInRange(10, 20, false); err != ErrNoBitAvailable {
622
-		t.Fatal("Expected error. Got success")
623
-	}
624
-	if err := hnd.Set(50); err != ErrBitAllocated {
625
-		t.Fatalf("Expected error. Got %v: %s", err, hnd)
626
-	}
627
-	i := uint64(0)
628
-	for hnd.Unselected() < numBits {
629
-		if err := hnd.Unset(i); err != nil {
630
-			t.Fatal(err)
631
-		}
632
-		i++
633
-	}
634
-}
635
-
636
-func TestOffsetSetUnset(t *testing.T) {
637
-	numBits := uint64(32 * blockLen)
638
-	var o uint64
639
-	hnd, err := NewHandle("", nil, "", numBits)
640
-	if err != nil {
641
-		t.Fatal(err)
642
-	}
643
-
644
-	// set and unset all one by one
645
-	for hnd.Unselected() > 0 {
646
-		if _, err := hnd.SetAny(false); err != nil {
647
-			t.Fatal(err)
648
-		}
649
-	}
650
-
651
-	if _, err := hnd.SetAny(false); err != ErrNoBitAvailable {
652
-		t.Fatal("Expected error. Got success")
653
-	}
654
-
655
-	if _, err := hnd.SetAnyInRange(10, 20, false); err != ErrNoBitAvailable {
656
-		t.Fatal("Expected error. Got success")
657
-	}
658
-
659
-	if err := hnd.Unset(288); err != nil {
660
-		t.Fatal(err)
661
-	}
662
-
663
-	//At this point sequence is (0xffffffff, 9)->(0x7fffffff, 1)->(0xffffffff, 22)->end
664
-	if o, err = hnd.SetAnyInRange(32, 500, false); err != nil {
665
-		t.Fatal(err)
666
-	}
667
-
668
-	if o != 288 {
669
-		t.Fatalf("Expected ordinal not received, Received:%d", o)
670
-	}
671
-}
672
-
673
-func TestSetInRange(t *testing.T) {
674
-	numBits := uint64(1024 * blockLen)
675
-	hnd, err := NewHandle("", nil, "", numBits)
676
-	if err != nil {
677
-		t.Fatal(err)
678
-	}
679
-	hnd.head = getTestSequence()
680
-
681
-	firstAv := uint64(100*blockLen + blockLen - 1)
682
-
683
-	if o, err := hnd.SetAnyInRange(4, 3, false); err == nil {
684
-		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
685
-	}
686
-
687
-	if o, err := hnd.SetAnyInRange(0, numBits, false); err == nil {
688
-		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
689
-	}
690
-
691
-	o, err := hnd.SetAnyInRange(100*uint64(blockLen), 101*uint64(blockLen), false)
692
-	if err != nil {
693
-		t.Fatalf("Unexpected failure: (%d, %v)", o, err)
694
-	}
695
-	if o != firstAv {
696
-		t.Fatalf("Unexpected ordinal: %d", o)
697
-	}
698
-
699
-	if o, err := hnd.SetAnyInRange(0, uint64(blockLen), false); err == nil {
700
-		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
701
-	}
702
-
703
-	if o, err := hnd.SetAnyInRange(0, firstAv-1, false); err == nil {
704
-		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
705
-	}
706
-
707
-	if o, err := hnd.SetAnyInRange(111*uint64(blockLen), 161*uint64(blockLen), false); err == nil {
708
-		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
709
-	}
710
-
711
-	o, err = hnd.SetAnyInRange(161*uint64(blockLen), 162*uint64(blockLen), false)
712
-	if err != nil {
713
-		t.Fatal(err)
714
-	}
715
-	if o != 161*uint64(blockLen)+30 {
716
-		t.Fatalf("Unexpected ordinal: %d", o)
717
-	}
718
-
719
-	o, err = hnd.SetAnyInRange(161*uint64(blockLen), 162*uint64(blockLen), false)
720
-	if err != nil {
721
-		t.Fatal(err)
722
-	}
723
-	if o != 161*uint64(blockLen)+31 {
724
-		t.Fatalf("Unexpected ordinal: %d", o)
725
-	}
726
-
727
-	o, err = hnd.SetAnyInRange(161*uint64(blockLen), 162*uint64(blockLen), false)
728
-	if err == nil {
729
-		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
730
-	}
731
-
732
-	if _, err := hnd.SetAnyInRange(0, numBits-1, false); err != nil {
733
-		t.Fatalf("Unexpected failure: %v", err)
734
-	}
735
-
736
-	// set one bit using the set range with 1 bit size range
737
-	if _, err := hnd.SetAnyInRange(uint64(163*blockLen-1), uint64(163*blockLen-1), false); err != nil {
738
-		t.Fatal(err)
739
-	}
740
-
741
-	// create a non multiple of 32 mask
742
-	hnd, err = NewHandle("", nil, "", 30)
743
-	if err != nil {
744
-		t.Fatal(err)
745
-	}
746
-
747
-	// set all bit in the first range
748
-	for hnd.Unselected() > 22 {
749
-		if o, err := hnd.SetAnyInRange(0, 7, false); err != nil {
750
-			t.Fatalf("Unexpected failure: (%d, %v)", o, err)
751
-		}
752
-	}
753
-	// try one more set, which should fail
754
-	o, err = hnd.SetAnyInRange(0, 7, false)
755
-	if err == nil {
756
-		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
757
-	}
758
-	if err != ErrNoBitAvailable {
759
-		t.Fatalf("Unexpected error: %v", err)
760
-	}
761
-
762
-	// set all bit in a second range
763
-	for hnd.Unselected() > 14 {
764
-		if o, err := hnd.SetAnyInRange(8, 15, false); err != nil {
765
-			t.Fatalf("Unexpected failure: (%d, %v)", o, err)
766
-		}
767
-	}
768
-
769
-	// try one more set, which should fail
770
-	o, err = hnd.SetAnyInRange(0, 15, false)
771
-	if err == nil {
772
-		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
773
-	}
774
-	if err != ErrNoBitAvailable {
775
-		t.Fatalf("Unexpected error: %v", err)
776
-	}
777
-
778
-	// set all bit in a range which includes the last bit
779
-	for hnd.Unselected() > 12 {
780
-		if o, err := hnd.SetAnyInRange(28, 29, false); err != nil {
781
-			t.Fatalf("Unexpected failure: (%d, %v)", o, err)
782
-		}
783
-	}
784
-	o, err = hnd.SetAnyInRange(28, 29, false)
785
-	if err == nil {
786
-		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
787
-	}
788
-	if err != ErrNoBitAvailable {
789
-		t.Fatalf("Unexpected error: %v", err)
790
-	}
791
-}
44
+const blockLen = 32
792 45
 
793 46
 // This one tests an allocation pattern which unveiled an issue in pushReservation
794 47
 // Specifically a failure in detecting when we are in the (B) case (the bit to set
... ...
@@ -845,39 +98,6 @@ func TestSetAnyInRange(t *testing.T) {
845 845
 	}
846 846
 }
847 847
 
848
-func TestMethods(t *testing.T) {
849
-	numBits := uint64(256 * blockLen)
850
-	hnd, err := NewHandle("path/to/data", nil, "sequence1", numBits)
851
-	if err != nil {
852
-		t.Fatal(err)
853
-	}
854
-
855
-	if hnd.Bits() != numBits {
856
-		t.Fatalf("Unexpected bit number: %d", hnd.Bits())
857
-	}
858
-
859
-	if hnd.Unselected() != numBits {
860
-		t.Fatalf("Unexpected bit number: %d", hnd.Unselected())
861
-	}
862
-
863
-	exp := "(0x0, 256)->end"
864
-	if hnd.head.toString() != exp {
865
-		t.Fatalf("Unexpected sequence string: %s", hnd.head.toString())
866
-	}
867
-
868
-	for i := 0; i < 192; i++ {
869
-		_, err := hnd.SetAny(false)
870
-		if err != nil {
871
-			t.Fatal(err)
872
-		}
873
-	}
874
-
875
-	exp = "(0xffffffff, 6)->(0x0, 250)->end"
876
-	if hnd.head.toString() != exp {
877
-		t.Fatalf("Unexpected sequence string: %s", hnd.head.toString())
878
-	}
879
-}
880
-
881 848
 func TestRandomAllocateDeallocate(t *testing.T) {
882 849
 	ds, err := randomLocalStore()
883 850
 	if err != nil {
... ...
@@ -889,171 +109,37 @@ func TestRandomAllocateDeallocate(t *testing.T) {
889 889
 	if err != nil {
890 890
 		t.Fatal(err)
891 891
 	}
892
+	defer func() {
893
+		if err := hnd.Destroy(); err != nil {
894
+			t.Fatal(err)
895
+		}
896
+	}()
892 897
 
893 898
 	seed := time.Now().Unix()
894
-	rand.Seed(seed)
899
+	rng := rand.New(rand.NewSource(seed))
895 900
 
896 901
 	// Allocate all bits using a random pattern
897
-	pattern := rand.Perm(numBits)
902
+	pattern := rng.Perm(numBits)
898 903
 	for _, bit := range pattern {
899 904
 		err := hnd.Set(uint64(bit))
900 905
 		if err != nil {
901
-			t.Fatalf("Unexpected failure on allocation of %d: %v.\nSeed: %d.\n%s", bit, err, seed, hnd)
906
+			t.Errorf("Unexpected failure on allocation of %d: %v.\nSeed: %d.\n%s", bit, err, seed, hnd)
902 907
 		}
903 908
 	}
904
-	if hnd.Unselected() != 0 {
905
-		t.Fatalf("Expected full sequence. Instead found %d free bits. Seed: %d.\n%s", hnd.unselected, seed, hnd)
906
-	}
907
-	if hnd.head.toString() != "(0xffffffff, 16)->end" {
908
-		t.Fatalf("Unexpected db: %s", hnd.head.toString())
909
+	if unselected := hnd.Unselected(); unselected != 0 {
910
+		t.Errorf("Expected full sequence. Instead found %d free bits. Seed: %d.\n%s", unselected, seed, hnd)
909 911
 	}
910 912
 
911 913
 	// Deallocate all bits using a random pattern
912
-	pattern = rand.Perm(numBits)
914
+	pattern = rng.Perm(numBits)
913 915
 	for _, bit := range pattern {
914 916
 		err := hnd.Unset(uint64(bit))
915 917
 		if err != nil {
916
-			t.Fatalf("Unexpected failure on deallocation of %d: %v.\nSeed: %d.\n%s", bit, err, seed, hnd)
917
-		}
918
-	}
919
-	if hnd.Unselected() != uint64(numBits) {
920
-		t.Fatalf("Expected full sequence. Instead found %d free bits. Seed: %d.\n%s", hnd.unselected, seed, hnd)
921
-	}
922
-	if hnd.head.toString() != "(0x0, 16)->end" {
923
-		t.Fatalf("Unexpected db: %s", hnd.head.toString())
924
-	}
925
-
926
-	err = hnd.Destroy()
927
-	if err != nil {
928
-		t.Fatal(err)
929
-	}
930
-}
931
-
932
-func TestAllocateRandomDeallocate(t *testing.T) {
933
-	ds, err := randomLocalStore()
934
-	if err != nil {
935
-		t.Fatal(err)
936
-	}
937
-
938
-	numBlocks := uint32(8)
939
-	numBits := int(numBlocks * blockLen)
940
-	hnd, err := NewHandle(filepath.Join("bitseq", "test", "data"), ds, "test1", uint64(numBits))
941
-	if err != nil {
942
-		t.Fatal(err)
943
-	}
944
-
945
-	expected := &sequence{block: 0xffffffff, count: uint64(numBlocks / 2), next: &sequence{block: 0x0, count: uint64(numBlocks / 2)}}
946
-
947
-	// Allocate first half of the bits
948
-	for i := 0; i < numBits/2; i++ {
949
-		_, err := hnd.SetAny(false)
950
-		if err != nil {
951
-			t.Fatalf("Unexpected failure on allocation %d: %v\n%s", i, err, hnd)
952
-		}
953
-	}
954
-	if hnd.Unselected() != uint64(numBits/2) {
955
-		t.Fatalf("Expected full sequence. Instead found %d free bits. %s", hnd.unselected, hnd)
956
-	}
957
-	if !hnd.head.equal(expected) {
958
-		t.Fatalf("Unexpected sequence. Got:\n%s", hnd)
959
-	}
960
-
961
-	seed := time.Now().Unix()
962
-	rand.Seed(seed)
963
-
964
-	// Deallocate half of the allocated bits following a random pattern
965
-	pattern := rand.Perm(numBits / 2)
966
-	for i := 0; i < numBits/4; i++ {
967
-		bit := pattern[i]
968
-		err := hnd.Unset(uint64(bit))
969
-		if err != nil {
970
-			t.Fatalf("Unexpected failure on deallocation of %d: %v.\nSeed: %d.\n%s", bit, err, seed, hnd)
971
-		}
972
-	}
973
-	if hnd.Unselected() != uint64(3*numBits/4) {
974
-		t.Fatalf("Expected full sequence. Instead found %d free bits.\nSeed: %d.\n%s", hnd.unselected, seed, hnd)
975
-	}
976
-
977
-	// Request a quarter of bits
978
-	for i := 0; i < numBits/4; i++ {
979
-		_, err := hnd.SetAny(false)
980
-		if err != nil {
981
-			t.Fatalf("Unexpected failure on allocation %d: %v\nSeed: %d\n%s", i, err, seed, hnd)
918
+			t.Errorf("Unexpected failure on deallocation of %d: %v.\nSeed: %d.\n%s", bit, err, seed, hnd)
982 919
 		}
983 920
 	}
984
-	if hnd.Unselected() != uint64(numBits/2) {
985
-		t.Fatalf("Expected half sequence. Instead found %d free bits.\nSeed: %d\n%s", hnd.unselected, seed, hnd)
986
-	}
987
-	if !hnd.head.equal(expected) {
988
-		t.Fatalf("Unexpected sequence. Got:\n%s", hnd)
989
-	}
990
-
991
-	err = hnd.Destroy()
992
-	if err != nil {
993
-		t.Fatal(err)
994
-	}
995
-}
996
-
997
-func TestAllocateRandomDeallocateSerialize(t *testing.T) {
998
-	ds, err := randomLocalStore()
999
-	if err != nil {
1000
-		t.Fatal(err)
1001
-	}
1002
-
1003
-	numBlocks := uint32(8)
1004
-	numBits := int(numBlocks * blockLen)
1005
-	hnd, err := NewHandle("bitseq-test/data/", ds, "test1", uint64(numBits))
1006
-	if err != nil {
1007
-		t.Fatal(err)
1008
-	}
1009
-
1010
-	expected := &sequence{block: 0xffffffff, count: uint64(numBlocks / 2), next: &sequence{block: 0x0, count: uint64(numBlocks / 2)}}
1011
-
1012
-	// Allocate first half of the bits
1013
-	for i := 0; i < numBits/2; i++ {
1014
-		_, err := hnd.SetAny(true)
1015
-		if err != nil {
1016
-			t.Fatalf("Unexpected failure on allocation %d: %v\n%s", i, err, hnd)
1017
-		}
1018
-	}
1019
-
1020
-	if hnd.Unselected() != uint64(numBits/2) {
1021
-		t.Fatalf("Expected full sequence. Instead found %d free bits. %s", hnd.unselected, hnd)
1022
-	}
1023
-	if !hnd.head.equal(expected) {
1024
-		t.Fatalf("Unexpected sequence. Got:\n%s", hnd)
1025
-	}
1026
-
1027
-	seed := time.Now().Unix()
1028
-	rand.Seed(seed)
1029
-
1030
-	// Deallocate half of the allocated bits following a random pattern
1031
-	pattern := rand.Perm(numBits / 2)
1032
-	for i := 0; i < numBits/4; i++ {
1033
-		bit := pattern[i]
1034
-		err := hnd.Unset(uint64(bit))
1035
-		if err != nil {
1036
-			t.Fatalf("Unexpected failure on deallocation of %d: %v.\nSeed: %d.\n%s", bit, err, seed, hnd)
1037
-		}
1038
-	}
1039
-	if hnd.Unselected() != uint64(3*numBits/4) {
1040
-		t.Fatalf("Expected full sequence. Instead found %d free bits.\nSeed: %d.\n%s", hnd.unselected, seed, hnd)
1041
-	}
1042
-
1043
-	// Request a quarter of bits
1044
-	for i := 0; i < numBits/4; i++ {
1045
-		_, err := hnd.SetAny(true)
1046
-		if err != nil {
1047
-			t.Fatalf("Unexpected failure on allocation %d: %v\nSeed: %d\n%s", i, err, seed, hnd)
1048
-		}
1049
-	}
1050
-	if hnd.Unselected() != uint64(numBits/2) {
1051
-		t.Fatalf("Expected half sequence. Instead found %d free bits.\nSeed: %d\n%s", hnd.unselected, seed, hnd)
1052
-	}
1053
-
1054
-	err = hnd.Destroy()
1055
-	if err != nil {
1056
-		t.Fatal(err)
921
+	if unselected := hnd.Unselected(); unselected != uint64(numBits) {
922
+		t.Errorf("Expected full sequence. Instead found %d free bits. Seed: %d.\n%s", unselected, seed, hnd)
1057 923
 	}
1058 924
 }
1059 925
 
... ...
@@ -1106,140 +192,22 @@ func TestIsCorrupted(t *testing.T) {
1106 1106
 		t.Fatal(err)
1107 1107
 	}
1108 1108
 
1109
-	if hnd.runConsistencyCheck() {
1110
-		t.Fatalf("Unexpected corrupted for %s", hnd)
1111
-	}
1112
-
1113 1109
 	if err := hnd.CheckConsistency(); err != nil {
1114 1110
 		t.Fatal(err)
1115 1111
 	}
1116 1112
 
1117
-	hnd.Set(0)
1118
-	if hnd.runConsistencyCheck() {
1119
-		t.Fatalf("Unexpected corrupted for %s", hnd)
1120
-	}
1121
-
1122
-	hnd.Set(1023)
1123
-	if hnd.runConsistencyCheck() {
1124
-		t.Fatalf("Unexpected corrupted for %s", hnd)
1125
-	}
1126
-
1113
+	_ = hnd.Set(0)
1127 1114
 	if err := hnd.CheckConsistency(); err != nil {
1128 1115
 		t.Fatal(err)
1129 1116
 	}
1130 1117
 
1131
-	// Try real corrupted ipam handles found in the local store files reported by three docker users,
1132
-	// plus a generic ipam handle from docker 1.9.1. This last will fail as well, because of how the
1133
-	// last node in the sequence is expressed (This is true for IPAM handle only, because of the broadcast
1134
-	// address reservation: last bit). This will allow an application using bitseq that runs a consistency
1135
-	// check to detect and replace the 1.9.0/1 old vulnerable handle with the new one.
1136
-	input := []*Handle{
1137
-		{
1138
-			id:         "LocalDefault/172.17.0.0/16",
1139
-			bits:       65536,
1140
-			unselected: 65412,
1141
-			head: &sequence{
1142
-				block: 0xffffffff,
1143
-				count: 3,
1144
-				next: &sequence{
1145
-					block: 0xffffffbf,
1146
-					count: 0,
1147
-					next: &sequence{
1148
-						block: 0xfe98816e,
1149
-						count: 1,
1150
-						next: &sequence{
1151
-							block: 0xffffffff,
1152
-							count: 0,
1153
-							next: &sequence{
1154
-								block: 0xe3bc0000,
1155
-								count: 1,
1156
-								next: &sequence{
1157
-									block: 0x0,
1158
-									count: 2042,
1159
-									next: &sequence{
1160
-										block: 0x1, count: 1,
1161
-										next: &sequence{
1162
-											block: 0x0, count: 0,
1163
-										},
1164
-									},
1165
-								},
1166
-							},
1167
-						},
1168
-					},
1169
-				},
1170
-			},
1171
-		},
1172
-		{
1173
-			id:         "LocalDefault/172.17.0.0/16",
1174
-			bits:       65536,
1175
-			unselected: 65319,
1176
-			head: &sequence{
1177
-				block: 0xffffffff,
1178
-				count: 7,
1179
-				next: &sequence{
1180
-					block: 0xffffff7f,
1181
-					count: 0,
1182
-					next: &sequence{
1183
-						block: 0xffffffff,
1184
-						count: 0,
1185
-						next: &sequence{
1186
-							block: 0x2000000,
1187
-							count: 1,
1188
-							next: &sequence{
1189
-								block: 0x0,
1190
-								count: 2039,
1191
-								next: &sequence{
1192
-									block: 0x1,
1193
-									count: 1,
1194
-									next: &sequence{
1195
-										block: 0x0,
1196
-										count: 0,
1197
-									},
1198
-								},
1199
-							},
1200
-						},
1201
-					},
1202
-				},
1203
-			},
1204
-		},
1205
-		{
1206
-			id:         "LocalDefault/172.17.0.0/16",
1207
-			bits:       65536,
1208
-			unselected: 65456,
1209
-			head: &sequence{
1210
-				block: 0xffffffff, count: 2,
1211
-				next: &sequence{
1212
-					block: 0xfffbffff, count: 0,
1213
-					next: &sequence{
1214
-						block: 0xffd07000, count: 1,
1215
-						next: &sequence{
1216
-							block: 0x0, count: 333,
1217
-							next: &sequence{
1218
-								block: 0x40000000, count: 1,
1219
-								next: &sequence{
1220
-									block: 0x0, count: 1710,
1221
-									next: &sequence{
1222
-										block: 0x1, count: 1,
1223
-										next: &sequence{
1224
-											block: 0x0, count: 0,
1225
-										},
1226
-									},
1227
-								},
1228
-							},
1229
-						},
1230
-					},
1231
-				},
1232
-			},
1233
-		},
1118
+	_ = hnd.Set(1023)
1119
+	if err := hnd.CheckConsistency(); err != nil {
1120
+		t.Fatal(err)
1234 1121
 	}
1235 1122
 
1236
-	for idx, hnd := range input {
1237
-		if !hnd.runConsistencyCheck() {
1238
-			t.Fatalf("Expected corrupted for (%d): %s", idx, hnd)
1239
-		}
1240
-		if hnd.runConsistencyCheck() {
1241
-			t.Fatalf("Sequence still marked corrupted (%d): %s", idx, hnd)
1242
-		}
1123
+	if err := hnd.CheckConsistency(); err != nil {
1124
+		t.Fatal(err)
1243 1125
 	}
1244 1126
 }
1245 1127
 
... ...
@@ -1264,15 +232,15 @@ func testSetRollover(t *testing.T, serial bool) {
1264 1264
 		}
1265 1265
 	}
1266 1266
 
1267
-	if hnd.Unselected() != uint64(numBits/2) {
1268
-		t.Fatalf("Expected full sequence. Instead found %d free bits. %s", hnd.unselected, hnd)
1267
+	if unselected := hnd.Unselected(); unselected != uint64(numBits/2) {
1268
+		t.Fatalf("Expected full sequence. Instead found %d free bits. %s", unselected, hnd)
1269 1269
 	}
1270 1270
 
1271 1271
 	seed := time.Now().Unix()
1272
-	rand.Seed(seed)
1272
+	rng := rand.New(rand.NewSource(seed))
1273 1273
 
1274 1274
 	// Deallocate half of the allocated bits following a random pattern
1275
-	pattern := rand.Perm(numBits / 2)
1275
+	pattern := rng.Perm(numBits / 2)
1276 1276
 	for i := 0; i < numBits/4; i++ {
1277 1277
 		bit := pattern[i]
1278 1278
 		err := hnd.Unset(uint64(bit))
... ...
@@ -1280,8 +248,8 @@ func testSetRollover(t *testing.T, serial bool) {
1280 1280
 			t.Fatalf("Unexpected failure on deallocation of %d: %v.\nSeed: %d.\n%s", bit, err, seed, hnd)
1281 1281
 		}
1282 1282
 	}
1283
-	if hnd.Unselected() != uint64(3*numBits/4) {
1284
-		t.Fatalf("Unexpected free bits: found %d free bits.\nSeed: %d.\n%s", hnd.unselected, seed, hnd)
1283
+	if unselected := hnd.Unselected(); unselected != uint64(3*numBits/4) {
1284
+		t.Fatalf("Unexpected free bits: found %d free bits.\nSeed: %d.\n%s", unselected, seed, hnd)
1285 1285
 	}
1286 1286
 
1287 1287
 	//request to allocate for remaining half of the bits
... ...
@@ -1294,8 +262,8 @@ func testSetRollover(t *testing.T, serial bool) {
1294 1294
 
1295 1295
 	//At this point all the bits must be allocated except the randomly unallocated bits
1296 1296
 	//which were unallocated in the first half of the bit sequence
1297
-	if hnd.Unselected() != uint64(numBits/4) {
1298
-		t.Fatalf("Unexpected number of unselected bits %d, Expected %d", hnd.Unselected(), numBits/4)
1297
+	if unselected := hnd.Unselected(); unselected != uint64(numBits/4) {
1298
+		t.Fatalf("Unexpected number of unselected bits %d, Expected %d", unselected, numBits/4)
1299 1299
 	}
1300 1300
 
1301 1301
 	for i := 0; i < numBits/4; i++ {
... ...
@@ -1324,38 +292,66 @@ func TestSetRolloverSerial(t *testing.T) {
1324 1324
 	testSetRollover(t, true)
1325 1325
 }
1326 1326
 
1327
-func TestGetFirstAvailableFromCurrent(t *testing.T) {
1328
-	input := []struct {
1329
-		mask    *sequence
1330
-		bytePos uint64
1331
-		bitPos  uint64
1332
-		start   uint64
1333
-		curr    uint64
1334
-		end     uint64
1335
-	}{
1336
-		{&sequence{block: 0xffffffff, count: 2048}, invalidPos, invalidPos, 0, 0, 65536},
1337
-		{&sequence{block: 0x0, count: 8}, 0, 0, 0, 0, 256},
1338
-		{&sequence{block: 0x80000000, count: 8}, 1, 0, 0, 8, 256},
1339
-		{&sequence{block: 0xC0000000, count: 8}, 0, 2, 0, 2, 256},
1340
-		{&sequence{block: 0xE0000000, count: 8}, 0, 3, 0, 0, 256},
1341
-		{&sequence{block: 0xFFFB1FFF, count: 8}, 2, 0, 14, 0, 256},
1342
-		{&sequence{block: 0xFFFFFFFE, count: 8}, 3, 7, 0, 0, 256},
1343
-
1344
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x00000000, count: 1, next: &sequence{block: 0xffffffff, count: 14}}}, 4, 0, 0, 32, 512},
1345
-		{&sequence{block: 0xfffeffff, count: 1, next: &sequence{block: 0xffffffff, count: 15}}, 1, 7, 0, 16, 512},
1346
-		{&sequence{block: 0xfffeffff, count: 15, next: &sequence{block: 0xffffffff, count: 1}}, 5, 7, 0, 16, 512},
1347
-		{&sequence{block: 0xfffeffff, count: 15, next: &sequence{block: 0xffffffff, count: 1}}, 9, 7, 0, 48, 512},
1348
-		{&sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0xffffffef, count: 14}}, 19, 3, 0, 124, 512},
1349
-		{&sequence{block: 0xfffeffff, count: 15, next: &sequence{block: 0x0fffffff, count: 1}}, 60, 0, 0, 480, 512},
1350
-		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xfffeffff, count: 14, next: &sequence{block: 0xffffffff, count: 1}}}, 17, 7, 0, 124, 512},
1351
-		{&sequence{block: 0xfffffffb, count: 1, next: &sequence{block: 0xffffffff, count: 14, next: &sequence{block: 0xffffffff, count: 1}}}, 3, 5, 0, 124, 512},
1352
-		{&sequence{block: 0xfffffffb, count: 1, next: &sequence{block: 0xfffeffff, count: 14, next: &sequence{block: 0xffffffff, count: 1}}}, 13, 7, 0, 80, 512},
1327
+func TestMarshalJSON(t *testing.T) {
1328
+	const expectedID = "my-bitseq"
1329
+	expected := []byte("hello libnetwork")
1330
+	hnd, err := NewHandle("", nil, expectedID, uint64(len(expected)*8))
1331
+	if err != nil {
1332
+		t.Fatal(err)
1353 1333
 	}
1354 1334
 
1355
-	for n, i := range input {
1356
-		bytePos, bitPos, _ := getAvailableFromCurrent(i.mask, i.start, i.curr, i.end)
1357
-		if bytePos != i.bytePos || bitPos != i.bitPos {
1358
-			t.Fatalf("Error in (%d) getFirstAvailable(). Expected (%d, %d). Got (%d, %d)", n, i.bytePos, i.bitPos, bytePos, bitPos)
1335
+	for i, c := range expected {
1336
+		for j := 0; j < 8; j++ {
1337
+			if c&(1<<j) == 0 {
1338
+				continue
1339
+			}
1340
+			if err := hnd.Set(uint64(i*8 + j)); err != nil {
1341
+				t.Fatal(err)
1342
+			}
1359 1343
 		}
1360 1344
 	}
1345
+
1346
+	hstr := hnd.String()
1347
+	t.Log(hstr)
1348
+	marshaled, err := hnd.MarshalJSON()
1349
+	if err != nil {
1350
+		t.Fatalf("MarshalJSON() err = %v", err)
1351
+	}
1352
+	t.Logf("%s", marshaled)
1353
+
1354
+	// Serializations of hnd as would be marshaled by versions of the code
1355
+	// found in the wild. We need to support unmarshaling old versions to
1356
+	// maintain backwards compatibility with sequences persisted on disk.
1357
+	const (
1358
+		goldenV0 = `{"id":"my-bitseq","sequence":"AAAAAAAAAIAAAAAAAAAAPRamNjYAAAAAAAAAAfYENpYAAAAAAAAAAUZ2pi4AAAAAAAAAAe72TtYAAAAAAAAAAQ=="}`
1359
+	)
1360
+
1361
+	if string(marshaled) != goldenV0 {
1362
+		t.Errorf("MarshalJSON() output differs from golden. Please add a new golden case to this test.")
1363
+	}
1364
+
1365
+	for _, tt := range []struct {
1366
+		name string
1367
+		data []byte
1368
+	}{
1369
+		{name: "Live", data: marshaled},
1370
+		{name: "Golden-v0", data: []byte(goldenV0)},
1371
+	} {
1372
+		tt := tt
1373
+		t.Run("UnmarshalJSON="+tt.name, func(t *testing.T) {
1374
+			hnd2, err := NewHandle("", nil, "", 0)
1375
+			if err != nil {
1376
+				t.Fatal(err)
1377
+			}
1378
+			if err := hnd2.UnmarshalJSON(tt.data); err != nil {
1379
+				t.Errorf("UnmarshalJSON() err = %v", err)
1380
+			}
1381
+
1382
+			h2str := hnd2.String()
1383
+			t.Log(h2str)
1384
+			if hstr != h2str {
1385
+				t.Errorf("Unmarshaled a different bitseq: want %q, got %q", hstr, h2str)
1386
+			}
1387
+		})
1388
+	}
1361 1389
 }
... ...
@@ -3,21 +3,22 @@ package bitseq
3 3
 import (
4 4
 	"encoding/json"
5 5
 
6
+	"github.com/docker/docker/libnetwork/bitmap"
6 7
 	"github.com/docker/docker/libnetwork/datastore"
7 8
 	"github.com/docker/docker/libnetwork/types"
8 9
 )
9 10
 
10 11
 // Key provides the Key to be used in KV Store
11 12
 func (h *Handle) Key() []string {
12
-	h.Lock()
13
-	defer h.Unlock()
13
+	h.mu.Lock()
14
+	defer h.mu.Unlock()
14 15
 	return []string{h.app, h.id}
15 16
 }
16 17
 
17 18
 // KeyPrefix returns the immediate parent key that can be used for tree walk
18 19
 func (h *Handle) KeyPrefix() []string {
19
-	h.Lock()
20
-	defer h.Unlock()
20
+	h.mu.Lock()
21
+	defer h.mu.Unlock()
21 22
 	return []string{h.app}
22 23
 }
23 24
 
... ...
@@ -37,30 +38,30 @@ func (h *Handle) SetValue(value []byte) error {
37 37
 
38 38
 // Index returns the latest DB Index as seen by this object
39 39
 func (h *Handle) Index() uint64 {
40
-	h.Lock()
41
-	defer h.Unlock()
40
+	h.mu.Lock()
41
+	defer h.mu.Unlock()
42 42
 	return h.dbIndex
43 43
 }
44 44
 
45 45
 // SetIndex method allows the datastore to store the latest DB Index into this object
46 46
 func (h *Handle) SetIndex(index uint64) {
47
-	h.Lock()
47
+	h.mu.Lock()
48 48
 	h.dbIndex = index
49 49
 	h.dbExists = true
50
-	h.Unlock()
50
+	h.mu.Unlock()
51 51
 }
52 52
 
53 53
 // Exists method is true if this object has been stored in the DB.
54 54
 func (h *Handle) Exists() bool {
55
-	h.Lock()
56
-	defer h.Unlock()
55
+	h.mu.Lock()
56
+	defer h.mu.Unlock()
57 57
 	return h.dbExists
58 58
 }
59 59
 
60 60
 // New method returns a handle based on the receiver handle
61 61
 func (h *Handle) New() datastore.KVObject {
62
-	h.Lock()
63
-	defer h.Unlock()
62
+	h.mu.Lock()
63
+	defer h.mu.Unlock()
64 64
 
65 65
 	return &Handle{
66 66
 		app:   h.app,
... ...
@@ -70,24 +71,21 @@ func (h *Handle) New() datastore.KVObject {
70 70
 
71 71
 // CopyTo deep copies the handle into the passed destination object
72 72
 func (h *Handle) CopyTo(o datastore.KVObject) error {
73
-	h.Lock()
74
-	defer h.Unlock()
73
+	h.mu.Lock()
74
+	defer h.mu.Unlock()
75 75
 
76 76
 	dstH := o.(*Handle)
77 77
 	if h == dstH {
78 78
 		return nil
79 79
 	}
80
-	dstH.Lock()
81
-	dstH.bits = h.bits
82
-	dstH.unselected = h.unselected
83
-	dstH.head = h.head.getCopy()
80
+	dstH.mu.Lock()
81
+	defer dstH.mu.Unlock()
82
+	dstH.bm = bitmap.Copy(h.bm)
84 83
 	dstH.app = h.app
85 84
 	dstH.id = h.id
86 85
 	dstH.dbIndex = h.dbIndex
87 86
 	dstH.dbExists = h.dbExists
88 87
 	dstH.store = h.store
89
-	dstH.curr = h.curr
90
-	dstH.Unlock()
91 88
 
92 89
 	return nil
93 90
 }
... ...
@@ -99,16 +97,16 @@ func (h *Handle) Skip() bool {
99 99
 
100 100
 // DataScope method returns the storage scope of the datastore
101 101
 func (h *Handle) DataScope() string {
102
-	h.Lock()
103
-	defer h.Unlock()
102
+	h.mu.Lock()
103
+	defer h.mu.Unlock()
104 104
 
105 105
 	return h.store.Scope()
106 106
 }
107 107
 
108 108
 func (h *Handle) writeToStore() error {
109
-	h.Lock()
109
+	h.mu.Lock()
110 110
 	store := h.store
111
-	h.Unlock()
111
+	h.mu.Unlock()
112 112
 	if store == nil {
113 113
 		return nil
114 114
 	}
... ...
@@ -120,9 +118,9 @@ func (h *Handle) writeToStore() error {
120 120
 }
121 121
 
122 122
 func (h *Handle) deleteFromStore() error {
123
-	h.Lock()
123
+	h.mu.Lock()
124 124
 	store := h.store
125
-	h.Unlock()
125
+	h.mu.Unlock()
126 126
 	if store == nil {
127 127
 		return nil
128 128
 	}