Skip to content

Commit

Permalink
go fmt + some extra optimizations (isFull)
Browse files Browse the repository at this point in the history
  • Loading branch information
lemire committed Mar 17, 2017
1 parent bfe519f commit 8a91ca4
Show file tree
Hide file tree
Showing 8 changed files with 850 additions and 36 deletions.
59 changes: 50 additions & 9 deletions arraycontainer.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,18 +302,36 @@ func (ac *arrayContainer) or(a container) container {
case *bitmapContainer:
return x.orArray(ac)
case *runContainer16:
if x.isFull() {
return x.clone()
}
return x.orArray(ac)
}
panic("unsupported container type")
}

func (ac *arrayContainer) orCardinality(a container) int {
switch x := a.(type) {
case *arrayContainer:
return ac.orArrayCardinality(x)
case *bitmapContainer:
return x.orArrayCardinality(ac)
case *runContainer16:
return x.orArrayCardinality(ac)
}
panic("unsupported container type")
}

func (ac *arrayContainer) ior(a container) container {
switch x := a.(type) {
case *arrayContainer:
return ac.iorArray(x)
case *bitmapContainer:
return ac.iorBitmap(x)
case *runContainer16:
if x.isFull() {
return x.clone()
}
return ac.iorRun16(x)
}
panic("unsupported container type")
Expand Down Expand Up @@ -412,6 +430,10 @@ func (ac *arrayContainer) orArray(value2 *arrayContainer) container {
return answer
}

func (ac *arrayContainer) orArrayCardinality(value2 *arrayContainer) int {
return union2by2Cardinality(ac.content, value2.content)
}

func (ac *arrayContainer) lazyorArray(value2 *arrayContainer) container {
value1 := ac
maxPossibleCardinality := value1.getCardinality() + value2.getCardinality()
Expand Down Expand Up @@ -446,11 +468,26 @@ func (ac *arrayContainer) and(a container) container {
case *bitmapContainer:
return x.and(ac)
case *runContainer16:
if x.isFull() {
return ac.clone()
}
return x.andArray(ac)
}
panic("unsupported container type")
}

func (ac *arrayContainer) andCardinality(a container) int {
switch x := a.(type) {
case *arrayContainer:
return ac.andArrayCardinality(x)
case *bitmapContainer:
return x.andCardinality(ac)
case *runContainer16:
return x.andArrayCardinality(ac)
}
panic("unsupported container type")
}

func (ac *arrayContainer) intersects(a container) bool {
switch x := a.(type) {
case *arrayContainer:
Expand All @@ -470,13 +507,15 @@ func (ac *arrayContainer) iand(a container) container {
case *bitmapContainer:
return ac.iandBitmap(x)
case *runContainer16:
if x.isFull() {
return ac.clone()
}
return ac.iandRun16(x)
}
panic("unsupported container type")
}

func (ac *arrayContainer) iandRun16(rc *runContainer16) container {

bc1 := ac.toBitmapContainer()
bc2 := newBitmapContainerFromRun(rc)
bc2.iandBitmap(bc1)
Expand Down Expand Up @@ -736,16 +775,12 @@ func min(a, b int) int {
}
return b
}
func (ac *arrayContainer) andArray(value2 *arrayContainer) container {

// are bitmaps faster? nope
/*
bc1 := ac.toBitmapContainer()
bc2 := value2.toBitmapContainer()
bc1.iandBitmap(bc2)
return bc1
*/
func (ac *arrayContainer) isFull() bool {
return false
}

func (ac *arrayContainer) andArray(value2 *arrayContainer) container {
desiredcapacity := min(ac.getCardinality(), value2.getCardinality())
answer := newArrayContainerCapacity(desiredcapacity)
length := intersection2by2(
Expand All @@ -756,6 +791,12 @@ func (ac *arrayContainer) andArray(value2 *arrayContainer) container {
return answer
}

func (ac *arrayContainer) andArrayCardinality(value2 *arrayContainer) int {
return intersection2by2Cardinality(
ac.content,
value2.content)
}

func (ac *arrayContainer) intersectsArray(value2 *arrayContainer) bool {
return intersects2by2(
ac.content,
Expand Down
113 changes: 107 additions & 6 deletions bitmapcontainer.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,22 +246,43 @@ func (bc *bitmapContainer) or(a container) container {
case *bitmapContainer:
return bc.orBitmap(x)
case *runContainer16:
if x.isFull() {
return x.clone()
}
return x.orBitmapContainer(bc)
}
panic("unsupported container type")
}

func (bc *bitmapContainer) orCardinality(a container) int {
switch x := a.(type) {
case *arrayContainer:
return bc.orArrayCardinality(x)
case *bitmapContainer:
return bc.orBitmapCardinality(x)
case *runContainer16:
return x.orBitmapContainerCardinality(bc)
}
panic("unsupported container type")
}

func (bc *bitmapContainer) ior(a container) container {
switch x := a.(type) {
case *arrayContainer:
return bc.iorArray(x)
case *bitmapContainer:
return bc.iorBitmap(x)
case *runContainer16:
if x.isFull() {
return x.clone()
}
for i := range x.iv {
bc.iaddRange(int(x.iv[i].start), int(x.iv[i].last)+1)
}
bc.computeCardinality()
if bc.isFull() {
return newRunContainer16Range(0, MaxUint16)
}
//bc.computeCardinality()
return bc
}
panic(fmt.Errorf("unsupported container type %T", a))
Expand All @@ -276,9 +297,10 @@ func (bc *bitmapContainer) lazyIOR(a container) container {
case *runContainer16:
// TODO : implement efficient in-place lazy OR to bitmap
for i := range x.iv {
bc.iaddRange(int(x.iv[i].start), int(x.iv[i].last)+1)
setBitmapRange(bc.bitmap, int(x.iv[i].start), int(x.iv[i].last)+1)
//bc.iaddRange(int(x.iv[i].start), int(x.iv[i].last)+1)
}
bc.computeCardinality()
//bc.computeCardinality()
return bc
}
panic("unsupported container type")
Expand Down Expand Up @@ -312,15 +334,40 @@ func (bc *bitmapContainer) orArray(value2 *arrayContainer) container {
return answer
}

func (bc *bitmapContainer) orArrayCardinality(value2 *arrayContainer) int {
answer := 0
c := value2.getCardinality()
for k := 0; k < c; k++ {
// branchless:
v := value2.content[k]
i := uint(v) >> 6
bef := bc.bitmap[i]
aft := bef | (uint64(1) << (v % 64))
answer += int((bef - aft) >> 63)
}
return answer
}

func (bc *bitmapContainer) orBitmap(value2 *bitmapContainer) container {
answer := newBitmapContainer()
for k := 0; k < len(answer.bitmap); k++ {
answer.bitmap[k] = bc.bitmap[k] | value2.bitmap[k]
}
answer.computeCardinality()
if answer.isFull() {
return newRunContainer16Range(0, MaxUint16)
}
return answer
}

func (bc *bitmapContainer) orBitmapCardinality(value2 *bitmapContainer) int {
return int(popcntOrSlice(bc.bitmap, value2.bitmap))
}

func (bc *bitmapContainer) andBitmapCardinality(value2 *bitmapContainer) int {
return int(popcntAndSlice(bc.bitmap, value2.bitmap))
}

func (bc *bitmapContainer) computeCardinality() {
bc.cardinality = int(popcntSlice(bc.bitmap))
}
Expand All @@ -334,6 +381,9 @@ func (bc *bitmapContainer) iorArray(ac *arrayContainer) container {
bc.bitmap[i] = aft
bc.cardinality += int((bef - aft) >> 63)
}
if bc.isFull() {
return newRunContainer16Range(0, MaxUint16)
}
return bc
}

Expand All @@ -344,6 +394,9 @@ func (bc *bitmapContainer) iorBitmap(value2 *bitmapContainer) container {
answer.bitmap[k] = bc.bitmap[k] | value2.bitmap[k]
}
answer.computeCardinality()
if bc.isFull() {
return newRunContainer16Range(0, MaxUint16)
}
return answer
}

Expand Down Expand Up @@ -437,6 +490,9 @@ func (bc *bitmapContainer) xorBitmap(value2 *bitmapContainer) container {
answer.bitmap[k] = bc.bitmap[k] ^ value2.bitmap[k]
}
answer.cardinality = newCardinality
if answer.isFull() {
return newRunContainer16Range(0, MaxUint16)
}
return answer
}
ac := newArrayContainerSize(newCardinality)
Expand All @@ -452,11 +508,26 @@ func (bc *bitmapContainer) and(a container) container {
case *bitmapContainer:
return bc.andBitmap(x)
case *runContainer16:
if x.isFull() {
return bc.clone()
}
return x.andBitmapContainer(bc)
}
panic("unsupported container type")
}

func (bc *bitmapContainer) andCardinality(a container) int {
switch x := a.(type) {
case *arrayContainer:
return bc.andArrayCardinality(x)
case *bitmapContainer:
return bc.andBitmapCardinality(x)
case *runContainer16:
return x.andBitmapContainerCardinality(bc)
}
panic("unsupported container type")
}

func (bc *bitmapContainer) intersects(a container) bool {
switch x := a.(type) {
case *arrayContainer:
Expand All @@ -477,6 +548,9 @@ func (bc *bitmapContainer) iand(a container) container {
case *bitmapContainer:
return bc.iandBitmap(x)
case *runContainer16:
if x.isFull() {
return bc.clone()
}
return bc.iandRun16(x)
}
panic("unsupported container type")
Expand All @@ -503,10 +577,35 @@ func (bc *bitmapContainer) andArray(value2 *arrayContainer) *arrayContainer {
pos += int(bc.bitValue(v))
}
answer.content = answer.content[:pos]

return answer
}

func (bc *bitmapContainer) andArrayCardinality(value2 *arrayContainer) int {
c := value2.getCardinality()
pos := 0
for k := 0; k < c; k++ {
v := value2.content[k]
pos += int(bc.bitValue(v))
}
return pos
}

func (bc *bitmapContainer) getCardinalityInRange(start, end uint) int {
if start >= end {
return 0
}
firstword := start / 64
endword := (end - 1) / 64
const allones = ^uint64(0)
if firstword == endword {
return int(popcount(bc.bitmap[firstword] & ((allones << (start % 64)) & (allones >> (64 - (end % 64))))))
}
answer := popcount(bc.bitmap[firstword] & (allones << (start % 64)))
answer += popcntSlice(bc.bitmap[firstword+1 : endword])
answer += popcount(bc.bitmap[endword] & (allones >> (64 - (end % 64))))
return int(answer)
}

func (bc *bitmapContainer) andBitmap(value2 *bitmapContainer) container {
newcardinality := int(popcntAndSlice(bc.bitmap, value2.bitmap))
if newcardinality > arrayDefaultMaxSize {
Expand Down Expand Up @@ -757,9 +856,11 @@ func newBitmapContainerFromRun(rc *runContainer16) *bitmapContainer {

bc := newBitmapContainer()
for i := range rc.iv {
bc.iaddRange(int(rc.iv[i].start), int(rc.iv[i].last)+1)
setBitmapRange(bc.bitmap, int(rc.iv[i].start), int(rc.iv[i].last)+1)
bc.cardinality += int(rc.iv[i].last) + 1 - int(rc.iv[i].start)
//bc.iaddRange(int(rc.iv[i].start), int(rc.iv[i].last)+1)
}
bc.computeCardinality()
//bc.computeCardinality()
return bc
}

Expand Down
2 changes: 2 additions & 0 deletions fastaggregation.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ func (x1 *Bitmap) repairAfterLazy() {
c.(*bitmapContainer).computeCardinality()
if c.(*bitmapContainer).getCardinality() <= arrayDefaultMaxSize {
x1.highlowcontainer.setContainerAtIndex(pos, c.(*bitmapContainer).toArrayContainer())
} else if c.(*bitmapContainer).isFull() {
x1.highlowcontainer.setContainerAtIndex(pos, newRunContainer16Range(0, MaxUint16))
}
}
}
Expand Down

0 comments on commit 8a91ca4

Please sign in to comment.