mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-09-05 08:10:50 +00:00
added copy optimization ; type check; and code cleanup
This commit is contained in:
parent
2182534cc7
commit
498045f25a
1 changed files with 48 additions and 54 deletions
|
|
@ -441,6 +441,39 @@ func (b *Bitmap) Difference(other *Bitmap) *Bitmap {
|
|||
return output
|
||||
}
|
||||
|
||||
// Xor returns the bitwise exclusive or of b and other.
|
||||
func (b *Bitmap) Xor(other *Bitmap) *Bitmap {
|
||||
output := &Bitmap{}
|
||||
|
||||
ki, ci := b.keys, b.containers
|
||||
kj, cj := other.keys, other.containers
|
||||
|
||||
for {
|
||||
var key uint64
|
||||
var container *container
|
||||
|
||||
ni, nj := len(ki), len(kj)
|
||||
if ni == 0 && nj == 0 { // eof(i,j)
|
||||
break
|
||||
} else if ni == 0 || (nj != 0 && ki[0] > kj[0]) { // eof(i) or i > j
|
||||
key, container = kj[0], cj[0].clone()
|
||||
kj, cj = kj[1:], cj[1:]
|
||||
} else if nj == 0 || (ki[0] < kj[0]) { // eof(j) or i < j
|
||||
key, container = ki[0], ci[0].clone()
|
||||
ki, ci = ki[1:], ci[1:]
|
||||
} else { // i == j
|
||||
key, container = ki[0], xor(ci[0], cj[0])
|
||||
ki, ci = ki[1:], ci[1:]
|
||||
kj, cj = kj[1:], cj[1:]
|
||||
}
|
||||
|
||||
output.keys = append(output.keys, key)
|
||||
output.containers = append(output.containers, container)
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
// removeEmptyContainers deletes all containers that have a count of zero.
|
||||
func (b *Bitmap) removeEmptyContainers() {
|
||||
for i := 0; i < len(b.containers); {
|
||||
|
|
@ -1563,37 +1596,6 @@ func differenceBitmapBitmap(a, b *container) *container {
|
|||
}
|
||||
return output
|
||||
}
|
||||
func (b *Bitmap) Xor(other *Bitmap) *Bitmap {
|
||||
output := &Bitmap{}
|
||||
|
||||
ki, ci := b.keys, b.containers
|
||||
kj, cj := other.keys, other.containers
|
||||
|
||||
for {
|
||||
var key uint64
|
||||
var container *container
|
||||
|
||||
ni, nj := len(ki), len(kj)
|
||||
if ni == 0 && nj == 0 { // eof(i,j)
|
||||
break
|
||||
} else if ni == 0 || (nj != 0 && ki[0] > kj[0]) { // eof(i) or i > j
|
||||
key, container = kj[0], cj[0].clone()
|
||||
kj, cj = kj[1:], cj[1:]
|
||||
} else if nj == 0 || (ki[0] < kj[0]) { // eof(j) or i < j
|
||||
key, container = ki[0], ci[0].clone()
|
||||
ki, ci = ki[1:], ci[1:]
|
||||
} else { // i == j
|
||||
key, container = ki[0], xor(ci[0], cj[0])
|
||||
ki, ci = ki[1:], ci[1:]
|
||||
kj, cj = kj[1:], cj[1:]
|
||||
}
|
||||
|
||||
output.keys = append(output.keys, key)
|
||||
output.containers = append(output.containers, container)
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
func xor(a, b *container) *container {
|
||||
if a.isArray() {
|
||||
|
|
@ -1643,32 +1645,20 @@ func xorArrayArray(a, b *container) *container {
|
|||
}
|
||||
|
||||
func xorArrayBitmap(a, b *container) *container {
|
||||
output := &container{}
|
||||
itr := newBufIterator(newBitmapIterator(b.bitmap))
|
||||
for i := 0; ; {
|
||||
vb, eof := itr.next()
|
||||
if i >= len(a.array) && eof {
|
||||
break
|
||||
} else if i >= len(a.array) {
|
||||
output.add(vb)
|
||||
continue
|
||||
} else if eof {
|
||||
output.add(a.array[i])
|
||||
i++
|
||||
continue
|
||||
}
|
||||
|
||||
va := a.array[i]
|
||||
if va < vb {
|
||||
output.add(va)
|
||||
i++
|
||||
itr.unread()
|
||||
} else if va > vb {
|
||||
output.add(vb)
|
||||
output := b.clone()
|
||||
for _, v := range a.array {
|
||||
if b.bitmapContains(v) {
|
||||
output.remove(v)
|
||||
} else {
|
||||
i++
|
||||
|
||||
output.add(v)
|
||||
}
|
||||
}
|
||||
|
||||
if output.count() < ArrayMaxSize {
|
||||
output.convertToArray()
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
|
|
@ -1682,6 +1672,10 @@ func xorBitmapBitmap(a, b *container) *container {
|
|||
output.bitmap[i] = v
|
||||
output.n += int(popcnt(v))
|
||||
}
|
||||
|
||||
if output.count() < ArrayMaxSize {
|
||||
output.convertToArray()
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue