Skip to content

Commit

Permalink
Merge pull request #14 from weaviate/or_performance_improvements_p2
Browse files Browse the repository at this point in the history
performance: Or method - dynamic newContainer vs insertAt
  • Loading branch information
antas-marcin authored Nov 19, 2024
2 parents 4c33a1b + 104f1ff commit 08464f0
Showing 1 changed file with 22 additions and 25 deletions.
47 changes: 22 additions & 25 deletions bitmap_opt.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,12 +284,11 @@ func orContainers(a, b, res *Bitmap, buf []uint16) {
off = b.keys.val(bi)
bc := b.getContainer(off)
if c := containerOrAlt(ac, bc, buf, 0); len(c) > 0 && getCardinality(c) > 0 {
// create a new container and update the key offset to this container.

// Since buffer is used in containers merge, result container has to be copied
// to the bitmap immediately and to let buffer be reused for next merge.
// Therefore container can not be copied at the end of method execution like
// other containers from bitmaps a or b.
// to the bitmap immediately to let buffer be reused in next merge,
// contrary to unique containers from bitmap a and b copied at the end of method execution

// create a new container and update the key offset to this container.
offset := res.newContainerNoClr(uint16(len(c)))
copy(res.data[offset:], c)
res.setKey(ak, offset)
Expand Down Expand Up @@ -399,26 +398,24 @@ func orContainersInRange(a, b *Bitmap, bi, bn int, buf []uint16) {
boff := b.keys.val(bi)
bc := b.getContainer(boff)
if c := containerOrAlt(ac, bc, buf, runInline); len(c) > 0 {
// Previously merged container were replacing the old one,
// first moving data to the right to free enough space for the
// merged container to fit.
// That solution turned out to be slower for large datasets than
// appending bitmap with entirely new container, as moving data
// is not needed in that case.
// Reference to prev container is then forgotten resulting in
// memory not being used optimally.

// Since buffer is used in containers merge, result container has to be copied
// to the bitmap immediately and to let buffer be reused for next merge.
// Therefore container can not be copied at the end of method execution like
// other containers from bitmap b.
offset := a.newContainerNoClr(uint16(len(c)))
copy(a.data[offset:], c)
a.setKey(ak, offset)

// // make room for container, replacing smaller one and update key offset to new container.
// a.insertAt(aoff, c)
// a.setKey(ak, aoff)
// to the bitmap immediately to let buffer be reused in next merge,
// contrary to unique containers from bitmap b copied at the end of method execution

// Replacing previous container with merged one, that requires moving data
// to the right to make enough space for merged container is slower
// than appending bitmap with entirely new container and "forgetting" old one
// for large bitmaps, so it is performed only on small ones
if an > 10 {
// create a new container and update the key offset to this container.
offset := a.newContainerNoClr(uint16(len(c)))
copy(a.data[offset:], c)
a.setKey(ak, offset)
} else {
// make room for container, replacing smaller one and update key offset to new container.
a.insertAt(aoff, c)
a.setKey(ak, aoff)
}
}
ai++
bi++
Expand Down Expand Up @@ -448,7 +445,7 @@ func orContainersInRange(a, b *Bitmap, bi, bn int, buf []uint16) {

if sizeContainers > 0 {
// ensure enough space for new containers and keys,
// allocate required memory just once avoid copying underlying data slice multiple times
// allocate required memory just once to avoid copying underlying data slice multiple times
a.expandNoLengthChange(sizeContainers + sizeKeys)
a.expandKeys(sizeKeys)

Expand Down

0 comments on commit 08464f0

Please sign in to comment.