Skip to content

Commit 84551f0

Browse files
authored
Merge pull request #132 from maciej/frombuffer-changes
roaringArray.fromBuffer() changes
2 parents 66171ee + 61fc009 commit 84551f0

File tree

2 files changed

+24
-22
lines changed

2 files changed

+24
-22
lines changed

roaringarray.go

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -541,28 +541,17 @@ func (ra *roaringArray) fromBuffer(buf []byte) (int64, error) {
541541
pos += 4
542542
var size uint32 // number of containers
543543
haveRunContainers := false
544-
var isRun *bitmapContainer
544+
var isRunBitmap []byte
545545

546546
// cookie header
547547
if cookie&0x0000FFFF == serialCookie {
548548
haveRunContainers = true
549549
size = uint32(uint16(cookie>>16) + 1) // number of containers
550550

551551
// create is-run-container bitmap
552-
bytesToRead := (int(size) + 7) / 8
553-
by := buf[pos : pos+bytesToRead]
554-
pos += bytesToRead
555-
isRun = newBitmapContainer()
556-
i := 0
557-
for ; len(by) >= 8; i++ {
558-
isRun.bitmap[i] = binary.LittleEndian.Uint64(by)
559-
by = by[8:]
560-
}
561-
if len(by) > 0 {
562-
bx := make([]byte, 8)
563-
copy(bx, by)
564-
isRun.bitmap[i] = binary.LittleEndian.Uint64(bx)
565-
}
552+
isRunBitmapSize := (int(size) + 7) / 8
553+
isRunBitmap = buf[pos : pos+isRunBitmapSize]
554+
pos += isRunBitmapSize
566555
} else if cookie == serialCookieNoRunContainer {
567556
size = binary.LittleEndian.Uint32(buf[pos:])
568557
pos += 4
@@ -580,14 +569,17 @@ func (ra *roaringArray) fromBuffer(buf []byte) (int64, error) {
580569
}
581570

582571
// Allocate slices upfront as number of containers is known
583-
ra.containers = make([]container, 0, size)
584-
ra.keys = make([]uint16, 0, size)
585-
ra.needCopyOnWrite = make([]bool, 0, size)
572+
ra.containers = make([]container, size)
573+
ra.keys = make([]uint16, size)
574+
ra.needCopyOnWrite = make([]bool, size)
586575

587576
for i := uint32(0); i < size; i++ {
588577
key := uint16(keycard[2*i])
589578
card := int(keycard[2*i+1]) + 1
590-
if haveRunContainers && isRun.contains(uint16(i)) {
579+
ra.keys[i] = key
580+
ra.needCopyOnWrite[i] = true
581+
582+
if haveRunContainers && isRunBitmap[i/8]&(1<<(i%8)) != 0 {
591583
// run container
592584
nr := binary.LittleEndian.Uint16(buf[pos:])
593585
pos += 2
@@ -596,22 +588,22 @@ func (ra *roaringArray) fromBuffer(buf []byte) (int64, error) {
596588
card: int64(card),
597589
}
598590
pos += int(nr) * 4
599-
ra.appendContainer(key, &nb, true)
591+
ra.containers[i] = &nb
600592
} else if card > arrayDefaultMaxSize {
601593
// bitmap container
602594
nb := bitmapContainer{
603595
cardinality: card,
604596
bitmap: byteSliceAsUint64Slice(buf[pos : pos+arrayDefaultMaxSize*2]),
605597
}
606598
pos += arrayDefaultMaxSize * 2
607-
ra.appendContainer(key, &nb, true)
599+
ra.containers[i] = &nb
608600
} else {
609601
// array container
610602
nb := arrayContainer{
611603
byteSliceAsUint16Slice(buf[pos : pos+card*2]),
612604
}
613605
pos += card * 2
614-
ra.appendContainer(key, &nb, true)
606+
ra.containers[i] = &nb
615607
}
616608
}
617609

serialization_generic.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,16 @@ func (bc *bitmapContainer) asLittleEndianByteSlice() []byte {
5959
return by
6060
}
6161

62+
func uint64SliceAsByteSlice(slice []uint64) []byte {
63+
by := make([]byte, len(slice)*8)
64+
65+
for i, v := range slice {
66+
binary.LittleEndian.PutUint64(by[i*8:], v)
67+
}
68+
69+
return by
70+
}
71+
6272
func byteSliceAsUint16Slice(slice []byte) []uint16 {
6373
if len(slice)%2 != 0 {
6474
panic("Slice size should be divisible by 2")

0 commit comments

Comments
 (0)