Skip to content

Commit

Permalink
Merge pull request #132 from maciej/frombuffer-changes
Browse files Browse the repository at this point in the history
roaringArray.fromBuffer() changes
  • Loading branch information
lemire authored Jan 31, 2018
2 parents 66171ee + 61fc009 commit 84551f0
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 22 deletions.
36 changes: 14 additions & 22 deletions roaringarray.go
Original file line number Diff line number Diff line change
Expand Up @@ -541,28 +541,17 @@ func (ra *roaringArray) fromBuffer(buf []byte) (int64, error) {
pos += 4
var size uint32 // number of containers
haveRunContainers := false
var isRun *bitmapContainer
var isRunBitmap []byte

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

// create is-run-container bitmap
bytesToRead := (int(size) + 7) / 8
by := buf[pos : pos+bytesToRead]
pos += bytesToRead
isRun = newBitmapContainer()
i := 0
for ; len(by) >= 8; i++ {
isRun.bitmap[i] = binary.LittleEndian.Uint64(by)
by = by[8:]
}
if len(by) > 0 {
bx := make([]byte, 8)
copy(bx, by)
isRun.bitmap[i] = binary.LittleEndian.Uint64(bx)
}
isRunBitmapSize := (int(size) + 7) / 8
isRunBitmap = buf[pos : pos+isRunBitmapSize]
pos += isRunBitmapSize
} else if cookie == serialCookieNoRunContainer {
size = binary.LittleEndian.Uint32(buf[pos:])
pos += 4
Expand All @@ -580,14 +569,17 @@ func (ra *roaringArray) fromBuffer(buf []byte) (int64, error) {
}

// Allocate slices upfront as number of containers is known
ra.containers = make([]container, 0, size)
ra.keys = make([]uint16, 0, size)
ra.needCopyOnWrite = make([]bool, 0, size)
ra.containers = make([]container, size)
ra.keys = make([]uint16, size)
ra.needCopyOnWrite = make([]bool, size)

for i := uint32(0); i < size; i++ {
key := uint16(keycard[2*i])
card := int(keycard[2*i+1]) + 1
if haveRunContainers && isRun.contains(uint16(i)) {
ra.keys[i] = key
ra.needCopyOnWrite[i] = true

if haveRunContainers && isRunBitmap[i/8]&(1<<(i%8)) != 0 {
// run container
nr := binary.LittleEndian.Uint16(buf[pos:])
pos += 2
Expand All @@ -596,22 +588,22 @@ func (ra *roaringArray) fromBuffer(buf []byte) (int64, error) {
card: int64(card),
}
pos += int(nr) * 4
ra.appendContainer(key, &nb, true)
ra.containers[i] = &nb
} else if card > arrayDefaultMaxSize {
// bitmap container
nb := bitmapContainer{
cardinality: card,
bitmap: byteSliceAsUint64Slice(buf[pos : pos+arrayDefaultMaxSize*2]),
}
pos += arrayDefaultMaxSize * 2
ra.appendContainer(key, &nb, true)
ra.containers[i] = &nb
} else {
// array container
nb := arrayContainer{
byteSliceAsUint16Slice(buf[pos : pos+card*2]),
}
pos += card * 2
ra.appendContainer(key, &nb, true)
ra.containers[i] = &nb
}
}

Expand Down
10 changes: 10 additions & 0 deletions serialization_generic.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,16 @@ func (bc *bitmapContainer) asLittleEndianByteSlice() []byte {
return by
}

func uint64SliceAsByteSlice(slice []uint64) []byte {
by := make([]byte, len(slice)*8)

for i, v := range slice {
binary.LittleEndian.PutUint64(by[i*8:], v)
}

return by
}

func byteSliceAsUint16Slice(slice []byte) []uint16 {
if len(slice)%2 != 0 {
panic("Slice size should be divisible by 2")
Expand Down

0 comments on commit 84551f0

Please sign in to comment.