added copy optimization ; type check; and code cleanup

This commit is contained in:
Todd Gruben 2017-05-30 11:18:05 -05:00
parent 2182534cc7
commit 498045f25a

View file

@ -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
}