Browse code

libnetwork/bitmap: dup from package bitseq

...in preparation for separating the bit-sequence datatype from the
datastore persistence (KVObject) concerns. The new package's contents
are identical to those of package libnetwork/bitseq to assist in
reviewing the changes made on each side of the split.

Signed-off-by: Cory Snider <csnider@mirantis.com>

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