| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183 |
- package roaring
- import (
- "fmt"
- "unsafe"
- )
- type bitmapContainer struct {
- cardinality int
- bitmap []uint64
- }
- func (bc bitmapContainer) String() string {
- var s string
- for it := bc.getShortIterator(); it.hasNext(); {
- s += fmt.Sprintf("%v, ", it.next())
- }
- return s
- }
- func newBitmapContainer() *bitmapContainer {
- p := new(bitmapContainer)
- size := (1 << 16) / 64
- p.bitmap = make([]uint64, size, size)
- return p
- }
- func newBitmapContainerwithRange(firstOfRun, lastOfRun int) *bitmapContainer {
- bc := newBitmapContainer()
- bc.cardinality = lastOfRun - firstOfRun + 1
- if bc.cardinality == maxCapacity {
- fill(bc.bitmap, uint64(0xffffffffffffffff))
- } else {
- firstWord := firstOfRun / 64
- lastWord := lastOfRun / 64
- zeroPrefixLength := uint64(firstOfRun & 63)
- zeroSuffixLength := uint64(63 - (lastOfRun & 63))
- fillRange(bc.bitmap, firstWord, lastWord+1, uint64(0xffffffffffffffff))
- bc.bitmap[firstWord] ^= ((uint64(1) << zeroPrefixLength) - 1)
- blockOfOnes := (uint64(1) << zeroSuffixLength) - 1
- maskOnLeft := blockOfOnes << (uint64(64) - zeroSuffixLength)
- bc.bitmap[lastWord] ^= maskOnLeft
- }
- return bc
- }
- func (bc *bitmapContainer) minimum() uint16 {
- for i := 0; i < len(bc.bitmap); i++ {
- w := bc.bitmap[i]
- if w != 0 {
- r := countTrailingZeros(w)
- return uint16(r + i*64)
- }
- }
- return MaxUint16
- }
- // i should be non-zero
- func clz(i uint64) int {
- n := 1
- x := uint32(i >> 32)
- if x == 0 {
- n += 32
- x = uint32(i)
- }
- if x>>16 == 0 {
- n += 16
- x = x << 16
- }
- if x>>24 == 0 {
- n += 8
- x = x << 8
- }
- if x>>28 == 0 {
- n += 4
- x = x << 4
- }
- if x>>30 == 0 {
- n += 2
- x = x << 2
- }
- return n - int(x>>31)
- }
- func (bc *bitmapContainer) maximum() uint16 {
- for i := len(bc.bitmap); i > 0; i-- {
- w := bc.bitmap[i-1]
- if w != 0 {
- r := clz(w)
- return uint16((i-1)*64 + 63 - r)
- }
- }
- return uint16(0)
- }
- func (bc *bitmapContainer) iterate(cb func(x uint16) bool) bool {
- iterator := bitmapContainerShortIterator{bc, bc.NextSetBit(0)}
- for iterator.hasNext() {
- if !cb(iterator.next()) {
- return false
- }
- }
- return true
- }
- type bitmapContainerShortIterator struct {
- ptr *bitmapContainer
- i int
- }
- func (bcsi *bitmapContainerShortIterator) next() uint16 {
- j := bcsi.i
- bcsi.i = bcsi.ptr.NextSetBit(uint(bcsi.i) + 1)
- return uint16(j)
- }
- func (bcsi *bitmapContainerShortIterator) hasNext() bool {
- return bcsi.i >= 0
- }
- func (bcsi *bitmapContainerShortIterator) peekNext() uint16 {
- return uint16(bcsi.i)
- }
- func (bcsi *bitmapContainerShortIterator) advanceIfNeeded(minval uint16) {
- if bcsi.hasNext() && bcsi.peekNext() < minval {
- bcsi.i = bcsi.ptr.NextSetBit(uint(minval))
- }
- }
- func newBitmapContainerShortIterator(a *bitmapContainer) *bitmapContainerShortIterator {
- return &bitmapContainerShortIterator{a, a.NextSetBit(0)}
- }
- func (bc *bitmapContainer) getShortIterator() shortPeekable {
- return newBitmapContainerShortIterator(bc)
- }
- type reverseBitmapContainerShortIterator struct {
- ptr *bitmapContainer
- i int
- }
- func (bcsi *reverseBitmapContainerShortIterator) next() uint16 {
- if bcsi.i == -1 {
- panic("reverseBitmapContainerShortIterator.next() going beyond what is available")
- }
- j := bcsi.i
- bcsi.i = bcsi.ptr.PrevSetBit(bcsi.i - 1)
- return uint16(j)
- }
- func (bcsi *reverseBitmapContainerShortIterator) hasNext() bool {
- return bcsi.i >= 0
- }
- func newReverseBitmapContainerShortIterator(a *bitmapContainer) *reverseBitmapContainerShortIterator {
- if a.cardinality == 0 {
- return &reverseBitmapContainerShortIterator{a, -1}
- }
- return &reverseBitmapContainerShortIterator{a, int(a.maximum())}
- }
- func (bc *bitmapContainer) getReverseIterator() shortIterable {
- return newReverseBitmapContainerShortIterator(bc)
- }
- type bitmapContainerManyIterator struct {
- ptr *bitmapContainer
- base int
- bitset uint64
- }
- func (bcmi *bitmapContainerManyIterator) nextMany(hs uint32, buf []uint32) int {
- n := 0
- base := bcmi.base
- bitset := bcmi.bitset
- for n < len(buf) {
- if bitset == 0 {
- base++
- if base >= len(bcmi.ptr.bitmap) {
- bcmi.base = base
- bcmi.bitset = bitset
- return n
- }
- bitset = bcmi.ptr.bitmap[base]
- continue
- }
- t := bitset & -bitset
- buf[n] = uint32(((base * 64) + int(popcount(t-1)))) | hs
- n = n + 1
- bitset ^= t
- }
- bcmi.base = base
- bcmi.bitset = bitset
- return n
- }
- func (bcmi *bitmapContainerManyIterator) nextMany64(hs uint64, buf []uint64) int {
- n := 0
- base := bcmi.base
- bitset := bcmi.bitset
- for n < len(buf) {
- if bitset == 0 {
- base++
- if base >= len(bcmi.ptr.bitmap) {
- bcmi.base = base
- bcmi.bitset = bitset
- return n
- }
- bitset = bcmi.ptr.bitmap[base]
- continue
- }
- t := bitset & -bitset
- buf[n] = uint64(((base * 64) + int(popcount(t-1)))) | hs
- n = n + 1
- bitset ^= t
- }
- bcmi.base = base
- bcmi.bitset = bitset
- return n
- }
- func newBitmapContainerManyIterator(a *bitmapContainer) *bitmapContainerManyIterator {
- return &bitmapContainerManyIterator{a, -1, 0}
- }
- func (bc *bitmapContainer) getManyIterator() manyIterable {
- return newBitmapContainerManyIterator(bc)
- }
- func (bc *bitmapContainer) getSizeInBytes() int {
- return len(bc.bitmap) * 8 // + bcBaseBytes
- }
- func (bc *bitmapContainer) serializedSizeInBytes() int {
- //return bc.Msgsize()// NOO! This breaks GetSerializedSizeInBytes
- return len(bc.bitmap) * 8
- }
- const bcBaseBytes = int(unsafe.Sizeof(bitmapContainer{}))
- // bitmapContainer doesn't depend on card, always fully allocated
- func bitmapContainerSizeInBytes() int {
- return bcBaseBytes + (1<<16)/8
- }
- func bitmapEquals(a, b []uint64) bool {
- if len(a) != len(b) {
- return false
- }
- for i, v := range a {
- if v != b[i] {
- return false
- }
- }
- return true
- }
- func (bc *bitmapContainer) fillLeastSignificant16bits(x []uint32, i int, mask uint32) int {
- // TODO: should be written as optimized assembly
- pos := i
- base := mask
- for k := 0; k < len(bc.bitmap); k++ {
- bitset := bc.bitmap[k]
- for bitset != 0 {
- t := bitset & -bitset
- x[pos] = base + uint32(popcount(t-1))
- pos++
- bitset ^= t
- }
- base += 64
- }
- return pos
- }
- func (bc *bitmapContainer) equals(o container) bool {
- srb, ok := o.(*bitmapContainer)
- if ok {
- if srb.cardinality != bc.cardinality {
- return false
- }
- return bitmapEquals(bc.bitmap, srb.bitmap)
- }
- // use generic comparison
- if bc.getCardinality() != o.getCardinality() {
- return false
- }
- ait := o.getShortIterator()
- bit := bc.getShortIterator()
- for ait.hasNext() {
- if bit.next() != ait.next() {
- return false
- }
- }
- return true
- }
- func (bc *bitmapContainer) iaddReturnMinimized(i uint16) container {
- bc.iadd(i)
- if bc.isFull() {
- return newRunContainer16Range(0, MaxUint16)
- }
- return bc
- }
- func (bc *bitmapContainer) iadd(i uint16) bool {
- x := int(i)
- previous := bc.bitmap[x/64]
- mask := uint64(1) << (uint(x) % 64)
- newb := previous | mask
- bc.bitmap[x/64] = newb
- bc.cardinality += int((previous ^ newb) >> (uint(x) % 64))
- return newb != previous
- }
- func (bc *bitmapContainer) iremoveReturnMinimized(i uint16) container {
- if bc.iremove(i) {
- if bc.cardinality == arrayDefaultMaxSize {
- return bc.toArrayContainer()
- }
- }
- return bc
- }
- // iremove returns true if i was found.
- func (bc *bitmapContainer) iremove(i uint16) bool {
- if bc.contains(i) {
- bc.cardinality--
- bc.bitmap[i/64] &^= (uint64(1) << (i % 64))
- return true
- }
- return false
- }
- func (bc *bitmapContainer) isFull() bool {
- return bc.cardinality == int(MaxUint16)+1
- }
- func (bc *bitmapContainer) getCardinality() int {
- return bc.cardinality
- }
- func (bc *bitmapContainer) isEmpty() bool {
- return bc.cardinality == 0
- }
- func (bc *bitmapContainer) clone() container {
- ptr := bitmapContainer{bc.cardinality, make([]uint64, len(bc.bitmap))}
- copy(ptr.bitmap, bc.bitmap[:])
- return &ptr
- }
- // add all values in range [firstOfRange,lastOfRange)
- func (bc *bitmapContainer) iaddRange(firstOfRange, lastOfRange int) container {
- bc.cardinality += setBitmapRangeAndCardinalityChange(bc.bitmap, firstOfRange, lastOfRange)
- return bc
- }
- // remove all values in range [firstOfRange,lastOfRange)
- func (bc *bitmapContainer) iremoveRange(firstOfRange, lastOfRange int) container {
- bc.cardinality += resetBitmapRangeAndCardinalityChange(bc.bitmap, firstOfRange, lastOfRange)
- if bc.getCardinality() <= arrayDefaultMaxSize {
- return bc.toArrayContainer()
- }
- return bc
- }
- // flip all values in range [firstOfRange,endx)
- func (bc *bitmapContainer) inot(firstOfRange, endx int) container {
- if endx-firstOfRange == maxCapacity {
- flipBitmapRange(bc.bitmap, firstOfRange, endx)
- bc.cardinality = maxCapacity - bc.cardinality
- } else if endx-firstOfRange > maxCapacity/2 {
- flipBitmapRange(bc.bitmap, firstOfRange, endx)
- bc.computeCardinality()
- } else {
- bc.cardinality += flipBitmapRangeAndCardinalityChange(bc.bitmap, firstOfRange, endx)
- }
- if bc.getCardinality() <= arrayDefaultMaxSize {
- return bc.toArrayContainer()
- }
- return bc
- }
- // flip all values in range [firstOfRange,endx)
- func (bc *bitmapContainer) not(firstOfRange, endx int) container {
- answer := bc.clone()
- return answer.inot(firstOfRange, endx)
- }
- func (bc *bitmapContainer) or(a container) container {
- switch x := a.(type) {
- case *arrayContainer:
- return bc.orArray(x)
- 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)
- }
- if bc.isFull() {
- return newRunContainer16Range(0, MaxUint16)
- }
- //bc.computeCardinality()
- return bc
- }
- panic(fmt.Errorf("unsupported container type %T", a))
- }
- func (bc *bitmapContainer) lazyIOR(a container) container {
- switch x := a.(type) {
- case *arrayContainer:
- return bc.lazyIORArray(x)
- case *bitmapContainer:
- return bc.lazyIORBitmap(x)
- case *runContainer16:
- if x.isFull() {
- return x.clone()
- }
- // Manually inlined setBitmapRange function
- bitmap := bc.bitmap
- for _, iv := range x.iv {
- start := int(iv.start)
- end := int(iv.last()) + 1
- if start >= end {
- continue
- }
- firstword := start / 64
- endword := (end - 1) / 64
- if firstword == endword {
- bitmap[firstword] |= (^uint64(0) << uint(start%64)) & (^uint64(0) >> (uint(-end) % 64))
- continue
- }
- bitmap[firstword] |= ^uint64(0) << uint(start%64)
- for i := firstword + 1; i < endword; i++ {
- bitmap[i] = ^uint64(0)
- }
- bitmap[endword] |= ^uint64(0) >> (uint(-end) % 64)
- }
- bc.cardinality = invalidCardinality
- return bc
- }
- panic("unsupported container type")
- }
- func (bc *bitmapContainer) lazyOR(a container) container {
- switch x := a.(type) {
- case *arrayContainer:
- return bc.lazyORArray(x)
- case *bitmapContainer:
- return bc.lazyORBitmap(x)
- case *runContainer16:
- if x.isFull() {
- return x.clone()
- }
- // TODO: implement lazy OR
- return x.orBitmapContainer(bc)
- }
- panic("unsupported container type")
- }
- func (bc *bitmapContainer) orArray(value2 *arrayContainer) container {
- answer := bc.clone().(*bitmapContainer)
- c := value2.getCardinality()
- for k := 0; k < c; k++ {
- v := value2.content[k]
- i := uint(v) >> 6
- bef := answer.bitmap[i]
- aft := bef | (uint64(1) << (v % 64))
- answer.bitmap[i] = aft
- answer.cardinality += int((bef - aft) >> 63)
- }
- 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))
- }
- func (bc *bitmapContainer) iorArray(ac *arrayContainer) container {
- for k := range ac.content {
- vc := ac.content[k]
- i := uint(vc) >> 6
- bef := bc.bitmap[i]
- aft := bef | (uint64(1) << (vc % 64))
- bc.bitmap[i] = aft
- bc.cardinality += int((bef - aft) >> 63)
- }
- if bc.isFull() {
- return newRunContainer16Range(0, MaxUint16)
- }
- return bc
- }
- func (bc *bitmapContainer) iorBitmap(value2 *bitmapContainer) container {
- answer := bc
- answer.cardinality = 0
- for k := 0; k < len(answer.bitmap); k++ {
- answer.bitmap[k] = bc.bitmap[k] | value2.bitmap[k]
- }
- answer.computeCardinality()
- if bc.isFull() {
- return newRunContainer16Range(0, MaxUint16)
- }
- return answer
- }
- func (bc *bitmapContainer) lazyIORArray(value2 *arrayContainer) container {
- answer := bc
- c := value2.getCardinality()
- for k := 0; k+3 < c; k += 4 {
- content := (*[4]uint16)(unsafe.Pointer(&value2.content[k]))
- vc0 := content[0]
- i0 := uint(vc0) >> 6
- answer.bitmap[i0] = answer.bitmap[i0] | (uint64(1) << (vc0 % 64))
- vc1 := content[1]
- i1 := uint(vc1) >> 6
- answer.bitmap[i1] = answer.bitmap[i1] | (uint64(1) << (vc1 % 64))
- vc2 := content[2]
- i2 := uint(vc2) >> 6
- answer.bitmap[i2] = answer.bitmap[i2] | (uint64(1) << (vc2 % 64))
- vc3 := content[3]
- i3 := uint(vc3) >> 6
- answer.bitmap[i3] = answer.bitmap[i3] | (uint64(1) << (vc3 % 64))
- }
- for k := c &^ 3; k < c; k++ {
- vc := value2.content[k]
- i := uint(vc) >> 6
- answer.bitmap[i] = answer.bitmap[i] | (uint64(1) << (vc % 64))
- }
- answer.cardinality = invalidCardinality
- return answer
- }
- func (bc *bitmapContainer) lazyORArray(value2 *arrayContainer) container {
- answer := bc.clone().(*bitmapContainer)
- return answer.lazyIORArray(value2)
- }
- func (bc *bitmapContainer) lazyIORBitmap(value2 *bitmapContainer) container {
- answer := bc
- for k := 0; k < len(answer.bitmap); k++ {
- answer.bitmap[k] = bc.bitmap[k] | value2.bitmap[k]
- }
- bc.cardinality = invalidCardinality
- return answer
- }
- func (bc *bitmapContainer) lazyORBitmap(value2 *bitmapContainer) container {
- answer := bc.clone().(*bitmapContainer)
- return answer.lazyIORBitmap(value2)
- }
- func (bc *bitmapContainer) xor(a container) container {
- switch x := a.(type) {
- case *arrayContainer:
- return bc.xorArray(x)
- case *bitmapContainer:
- return bc.xorBitmap(x)
- case *runContainer16:
- return x.xorBitmap(bc)
- }
- panic("unsupported container type")
- }
- func (bc *bitmapContainer) xorArray(value2 *arrayContainer) container {
- answer := bc.clone().(*bitmapContainer)
- c := value2.getCardinality()
- for k := 0; k < c; k++ {
- vc := value2.content[k]
- index := uint(vc) >> 6
- abi := answer.bitmap[index]
- mask := uint64(1) << (vc % 64)
- answer.cardinality += 1 - 2*int((abi&mask)>>(vc%64))
- answer.bitmap[index] = abi ^ mask
- }
- if answer.cardinality <= arrayDefaultMaxSize {
- return answer.toArrayContainer()
- }
- return answer
- }
- func (bc *bitmapContainer) rank(x uint16) int {
- // TODO: rewrite in assembly
- leftover := (uint(x) + 1) & 63
- if leftover == 0 {
- return int(popcntSlice(bc.bitmap[:(uint(x)+1)/64]))
- }
- return int(popcntSlice(bc.bitmap[:(uint(x)+1)/64]) + popcount(bc.bitmap[(uint(x)+1)/64]<<(64-leftover)))
- }
- func (bc *bitmapContainer) selectInt(x uint16) int {
- remaining := x
- for k := 0; k < len(bc.bitmap); k++ {
- w := popcount(bc.bitmap[k])
- if uint16(w) > remaining {
- return k*64 + selectBitPosition(bc.bitmap[k], int(remaining))
- }
- remaining -= uint16(w)
- }
- return -1
- }
- func (bc *bitmapContainer) xorBitmap(value2 *bitmapContainer) container {
- newCardinality := int(popcntXorSlice(bc.bitmap, value2.bitmap))
- if newCardinality > arrayDefaultMaxSize {
- answer := newBitmapContainer()
- for k := 0; k < len(answer.bitmap); k++ {
- answer.bitmap[k] = bc.bitmap[k] ^ value2.bitmap[k]
- }
- answer.cardinality = newCardinality
- if answer.isFull() {
- return newRunContainer16Range(0, MaxUint16)
- }
- return answer
- }
- ac := newArrayContainerSize(newCardinality)
- fillArrayXOR(ac.content, bc.bitmap, value2.bitmap)
- ac.content = ac.content[:newCardinality]
- return ac
- }
- func (bc *bitmapContainer) and(a container) container {
- switch x := a.(type) {
- case *arrayContainer:
- return bc.andArray(x)
- 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:
- return bc.intersectsArray(x)
- case *bitmapContainer:
- return bc.intersectsBitmap(x)
- case *runContainer16:
- return x.intersects(bc)
- }
- panic("unsupported container type")
- }
- func (bc *bitmapContainer) iand(a container) container {
- switch x := a.(type) {
- case *arrayContainer:
- return bc.iandArray(x)
- case *bitmapContainer:
- return bc.iandBitmap(x)
- case *runContainer16:
- if x.isFull() {
- return bc.clone()
- }
- return bc.iandRun16(x)
- }
- panic("unsupported container type")
- }
- func (bc *bitmapContainer) iandRun16(rc *runContainer16) container {
- rcb := newBitmapContainerFromRun(rc)
- return bc.iandBitmap(rcb)
- }
- func (bc *bitmapContainer) iandArray(ac *arrayContainer) container {
- acb := ac.toBitmapContainer()
- return bc.iandBitmap(acb)
- }
- func (bc *bitmapContainer) andArray(value2 *arrayContainer) *arrayContainer {
- answer := newArrayContainerCapacity(len(value2.content))
- answer.content = answer.content[:cap(answer.content)]
- c := value2.getCardinality()
- pos := 0
- for k := 0; k < c; k++ {
- v := value2.content[k]
- answer.content[pos] = v
- 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) & 63)))))
- }
- answer := popcount(bc.bitmap[firstword] & (allones << (start % 64)))
- answer += popcntSlice(bc.bitmap[firstword+1 : endword])
- answer += popcount(bc.bitmap[endword] & (allones >> ((64 - end) & 63)))
- return int(answer)
- }
- func (bc *bitmapContainer) andBitmap(value2 *bitmapContainer) container {
- newcardinality := int(popcntAndSlice(bc.bitmap, value2.bitmap))
- if newcardinality > arrayDefaultMaxSize {
- answer := newBitmapContainer()
- for k := 0; k < len(answer.bitmap); k++ {
- answer.bitmap[k] = bc.bitmap[k] & value2.bitmap[k]
- }
- answer.cardinality = newcardinality
- return answer
- }
- ac := newArrayContainerSize(newcardinality)
- fillArrayAND(ac.content, bc.bitmap, value2.bitmap)
- ac.content = ac.content[:newcardinality] //not sure why i need this
- return ac
- }
- func (bc *bitmapContainer) intersectsArray(value2 *arrayContainer) bool {
- c := value2.getCardinality()
- for k := 0; k < c; k++ {
- v := value2.content[k]
- if bc.contains(v) {
- return true
- }
- }
- return false
- }
- func (bc *bitmapContainer) intersectsBitmap(value2 *bitmapContainer) bool {
- for k := 0; k < len(bc.bitmap); k++ {
- if (bc.bitmap[k] & value2.bitmap[k]) != 0 {
- return true
- }
- }
- return false
- }
- func (bc *bitmapContainer) iandBitmap(value2 *bitmapContainer) container {
- newcardinality := int(popcntAndSlice(bc.bitmap, value2.bitmap))
- for k := 0; k < len(bc.bitmap); k++ {
- bc.bitmap[k] = bc.bitmap[k] & value2.bitmap[k]
- }
- bc.cardinality = newcardinality
- if newcardinality <= arrayDefaultMaxSize {
- return newArrayContainerFromBitmap(bc)
- }
- return bc
- }
- func (bc *bitmapContainer) andNot(a container) container {
- switch x := a.(type) {
- case *arrayContainer:
- return bc.andNotArray(x)
- case *bitmapContainer:
- return bc.andNotBitmap(x)
- case *runContainer16:
- return bc.andNotRun16(x)
- }
- panic("unsupported container type")
- }
- func (bc *bitmapContainer) andNotRun16(rc *runContainer16) container {
- rcb := rc.toBitmapContainer()
- return bc.andNotBitmap(rcb)
- }
- func (bc *bitmapContainer) iandNot(a container) container {
- switch x := a.(type) {
- case *arrayContainer:
- return bc.iandNotArray(x)
- case *bitmapContainer:
- return bc.iandNotBitmapSurely(x)
- case *runContainer16:
- return bc.iandNotRun16(x)
- }
- panic("unsupported container type")
- }
- func (bc *bitmapContainer) iandNotArray(ac *arrayContainer) container {
- acb := ac.toBitmapContainer()
- return bc.iandNotBitmapSurely(acb)
- }
- func (bc *bitmapContainer) iandNotRun16(rc *runContainer16) container {
- rcb := rc.toBitmapContainer()
- return bc.iandNotBitmapSurely(rcb)
- }
- func (bc *bitmapContainer) andNotArray(value2 *arrayContainer) container {
- answer := bc.clone().(*bitmapContainer)
- c := value2.getCardinality()
- for k := 0; k < c; k++ {
- vc := value2.content[k]
- i := uint(vc) >> 6
- oldv := answer.bitmap[i]
- newv := oldv &^ (uint64(1) << (vc % 64))
- answer.bitmap[i] = newv
- answer.cardinality -= int((oldv ^ newv) >> (vc % 64))
- }
- if answer.cardinality <= arrayDefaultMaxSize {
- return answer.toArrayContainer()
- }
- return answer
- }
- func (bc *bitmapContainer) andNotBitmap(value2 *bitmapContainer) container {
- newCardinality := int(popcntMaskSlice(bc.bitmap, value2.bitmap))
- if newCardinality > arrayDefaultMaxSize {
- answer := newBitmapContainer()
- for k := 0; k < len(answer.bitmap); k++ {
- answer.bitmap[k] = bc.bitmap[k] &^ value2.bitmap[k]
- }
- answer.cardinality = newCardinality
- return answer
- }
- ac := newArrayContainerSize(newCardinality)
- fillArrayANDNOT(ac.content, bc.bitmap, value2.bitmap)
- return ac
- }
- func (bc *bitmapContainer) iandNotBitmapSurely(value2 *bitmapContainer) container {
- newCardinality := int(popcntMaskSlice(bc.bitmap, value2.bitmap))
- for k := 0; k < len(bc.bitmap); k++ {
- bc.bitmap[k] = bc.bitmap[k] &^ value2.bitmap[k]
- }
- bc.cardinality = newCardinality
- if bc.getCardinality() <= arrayDefaultMaxSize {
- return bc.toArrayContainer()
- }
- return bc
- }
- func (bc *bitmapContainer) contains(i uint16) bool { //testbit
- x := uint(i)
- w := bc.bitmap[x>>6]
- mask := uint64(1) << (x & 63)
- return (w & mask) != 0
- }
- func (bc *bitmapContainer) bitValue(i uint16) uint64 {
- x := uint(i)
- w := bc.bitmap[x>>6]
- return (w >> (x & 63)) & 1
- }
- func (bc *bitmapContainer) loadData(arrayContainer *arrayContainer) {
- bc.cardinality = arrayContainer.getCardinality()
- c := arrayContainer.getCardinality()
- for k := 0; k < c; k++ {
- x := arrayContainer.content[k]
- i := int(x) / 64
- bc.bitmap[i] |= (uint64(1) << uint(x%64))
- }
- }
- func (bc *bitmapContainer) resetTo(a container) {
- switch x := a.(type) {
- case *arrayContainer:
- fill(bc.bitmap, 0)
- bc.loadData(x)
- case *bitmapContainer:
- bc.cardinality = x.cardinality
- copy(bc.bitmap, x.bitmap)
- case *runContainer16:
- bc.cardinality = len(x.iv)
- lastEnd := 0
- for _, r := range x.iv {
- bc.cardinality += int(r.length)
- resetBitmapRange(bc.bitmap, lastEnd, int(r.start))
- lastEnd = int(r.start+r.length) + 1
- setBitmapRange(bc.bitmap, int(r.start), lastEnd)
- }
- resetBitmapRange(bc.bitmap, lastEnd, maxCapacity)
- default:
- panic("unsupported container type")
- }
- }
- func (bc *bitmapContainer) toArrayContainer() *arrayContainer {
- ac := &arrayContainer{}
- ac.loadData(bc)
- return ac
- }
- func (bc *bitmapContainer) fillArray(container []uint16) {
- //TODO: rewrite in assembly
- pos := 0
- base := 0
- for k := 0; k < len(bc.bitmap); k++ {
- bitset := bc.bitmap[k]
- for bitset != 0 {
- t := bitset & -bitset
- container[pos] = uint16((base + int(popcount(t-1))))
- pos = pos + 1
- bitset ^= t
- }
- base += 64
- }
- }
- func (bc *bitmapContainer) NextSetBit(i uint) int {
- var (
- x = i / 64
- length = uint(len(bc.bitmap))
- )
- if x >= length {
- return -1
- }
- w := bc.bitmap[x]
- w = w >> uint(i%64)
- if w != 0 {
- return int(i) + countTrailingZeros(w)
- }
- x++
- for ; x < length; x++ {
- if bc.bitmap[x] != 0 {
- return int(x*64) + countTrailingZeros(bc.bitmap[x])
- }
- }
- return -1
- }
- func (bc *bitmapContainer) PrevSetBit(i int) int {
- if i < 0 {
- return -1
- }
- x := i / 64
- if x >= len(bc.bitmap) {
- return -1
- }
- w := bc.bitmap[x]
- b := i % 64
- w = w << uint(63-b)
- if w != 0 {
- return i - countLeadingZeros(w)
- }
- x--
- for ; x >= 0; x-- {
- if bc.bitmap[x] != 0 {
- return (x * 64) + 63 - countLeadingZeros(bc.bitmap[x])
- }
- }
- return -1
- }
- // reference the java implementation
- // https://github.com/RoaringBitmap/RoaringBitmap/blob/master/src/main/java/org/roaringbitmap/BitmapContainer.java#L875-L892
- //
- func (bc *bitmapContainer) numberOfRuns() int {
- if bc.cardinality == 0 {
- return 0
- }
- var numRuns uint64
- nextWord := bc.bitmap[0]
- for i := 0; i < len(bc.bitmap)-1; i++ {
- word := nextWord
- nextWord = bc.bitmap[i+1]
- numRuns += popcount((^word)&(word<<1)) + ((word >> 63) &^ nextWord)
- }
- word := nextWord
- numRuns += popcount((^word) & (word << 1))
- if (word & 0x8000000000000000) != 0 {
- numRuns++
- }
- return int(numRuns)
- }
- // convert to run or array *if needed*
- func (bc *bitmapContainer) toEfficientContainer() container {
- numRuns := bc.numberOfRuns()
- sizeAsRunContainer := runContainer16SerializedSizeInBytes(numRuns)
- sizeAsBitmapContainer := bitmapContainerSizeInBytes()
- card := bc.getCardinality()
- sizeAsArrayContainer := arrayContainerSizeInBytes(card)
- if sizeAsRunContainer <= minOfInt(sizeAsBitmapContainer, sizeAsArrayContainer) {
- return newRunContainer16FromBitmapContainer(bc)
- }
- if card <= arrayDefaultMaxSize {
- return bc.toArrayContainer()
- }
- return bc
- }
- func newBitmapContainerFromRun(rc *runContainer16) *bitmapContainer {
- if len(rc.iv) == 1 {
- return newBitmapContainerwithRange(int(rc.iv[0].start), int(rc.iv[0].last()))
- }
- bc := newBitmapContainer()
- for i := range rc.iv {
- 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.computeCardinality()
- return bc
- }
- func (bc *bitmapContainer) containerType() contype {
- return bitmapContype
- }
- func (bc *bitmapContainer) addOffset(x uint16) (container, container) {
- var low, high *bitmapContainer
- if bc.cardinality == 0 {
- return nil, nil
- }
- b := uint32(x) >> 6
- i := uint32(x) % 64
- end := uint32(1024) - b
- low = newBitmapContainer()
- if i == 0 {
- copy(low.bitmap[b:], bc.bitmap[:end])
- } else {
- low.bitmap[b] = bc.bitmap[0] << i
- for k := uint32(1); k < end; k++ {
- newval := bc.bitmap[k] << i
- newval |= bc.bitmap[k-1] >> (64 - i)
- low.bitmap[b+k] = newval
- }
- }
- low.computeCardinality()
- if low.cardinality == bc.cardinality {
- // All elements from bc ended up in low, meaning high will be empty.
- return low, nil
- }
- if low.cardinality == 0 {
- // low is empty, let's reuse the container for high.
- high = low
- low = nil
- } else {
- // None of the containers will be empty, so allocate both.
- high = newBitmapContainer()
- }
- if i == 0 {
- copy(high.bitmap[:b], bc.bitmap[end:])
- } else {
- for k := end; k < 1024; k++ {
- newval := bc.bitmap[k] << i
- newval |= bc.bitmap[k-1] >> (64 - i)
- high.bitmap[k-end] = newval
- }
- high.bitmap[b] = bc.bitmap[1023] >> (64 - i)
- }
- high.computeCardinality()
- // Ensure proper nil interface.
- if low == nil {
- return nil, high
- }
- return low, high
- }
|