mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-08-28 10:54:59 +00:00
merge conflicts
This commit is contained in:
parent
6374fedd7a
commit
2d458b98a1
6 changed files with 73 additions and 499 deletions
|
|
@ -1,68 +0,0 @@
|
|||
// Copyright 2017 Pilosa Corp.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package roaring
|
||||
|
||||
|
||||
// bit population count, take from
|
||||
// https://code.google.com/p/go/issues/detail?id=4988#c11
|
||||
// credit: https://code.google.com/u/arnehormann/
|
||||
func popcntGo(x uint64) (n uint64) {
|
||||
x -= (x >> 1) & 0x5555555555555555
|
||||
x = (x>>2)&0x3333333333333333 + x&0x3333333333333333
|
||||
x += x >> 4
|
||||
x &= 0x0f0f0f0f0f0f0f0f
|
||||
x *= 0x0101010101010101
|
||||
return x >> 56
|
||||
}
|
||||
|
||||
func popcntSliceGo(s []uint64) uint64 {
|
||||
cnt := uint64(0)
|
||||
for _, x := range s {
|
||||
cnt += popcntGo(x)
|
||||
}
|
||||
return cnt
|
||||
}
|
||||
|
||||
func popcntMaskSliceGo(s, m []uint64) uint64 {
|
||||
cnt := uint64(0)
|
||||
for i := range s {
|
||||
cnt += popcntGo(s[i] &^ m[i])
|
||||
}
|
||||
return cnt
|
||||
}
|
||||
|
||||
func popcntAndSliceGo(s, m []uint64) uint64 {
|
||||
cnt := uint64(0)
|
||||
for i := range s {
|
||||
cnt += popcntGo(s[i] & m[i])
|
||||
}
|
||||
return cnt
|
||||
}
|
||||
|
||||
func popcntOrSliceGo(s, m []uint64) uint64 {
|
||||
cnt := uint64(0)
|
||||
for i := range s {
|
||||
cnt += popcntGo(s[i] | m[i])
|
||||
}
|
||||
return cnt
|
||||
}
|
||||
|
||||
func popcntXorSliceGo(s, m []uint64) uint64 {
|
||||
cnt := uint64(0)
|
||||
for i := range s {
|
||||
cnt += popcntGo(s[i] ^ m[i])
|
||||
}
|
||||
return cnt
|
||||
}
|
||||
|
|
@ -1,122 +0,0 @@
|
|||
#include "textflag.h"
|
||||
|
||||
TEXT ·hasAsm(SB),4,$0-1
|
||||
MOVQ $1, AX
|
||||
CPUID
|
||||
SHRQ $23, CX
|
||||
ANDQ $1, CX
|
||||
MOVB CX, ret+0(FP)
|
||||
RET
|
||||
|
||||
TEXT ·POPCNTQ(SB),NOSPLIT,$0-16
|
||||
MOVQ memory+0(FP), BP
|
||||
POPCNTQ BP, BX
|
||||
MOVQ BX, ret+8(FP)
|
||||
RET
|
||||
|
||||
TEXT ·BSFQ(SB),NOSPLIT,$0-16
|
||||
MOVQ memory+0(FP), BP
|
||||
BSFQ BP, BX
|
||||
MOVQ BX, ret+8(FP)
|
||||
RET
|
||||
|
||||
#define POPCNTQ_DX_DX BYTE $0xf3; BYTE $0x48; BYTE $0x0f; BYTE $0xb8; BYTE $0xd2
|
||||
|
||||
TEXT ·popcntSliceAsm(SB),4,$0-32
|
||||
XORQ AX, AX
|
||||
MOVQ s_base+0(FP), SI
|
||||
MOVQ s_len+8(FP), CX
|
||||
TESTQ CX, CX
|
||||
JZ popcntSliceEnd
|
||||
popcntSliceLoop:
|
||||
BYTE $0xf3; BYTE $0x48; BYTE $0x0f; BYTE $0xb8; BYTE $0x16 // POPCNTQ (SI), DX
|
||||
ADDQ DX, AX
|
||||
ADDQ $8, SI
|
||||
LOOP popcntSliceLoop
|
||||
popcntSliceEnd:
|
||||
MOVQ AX, ret+24(FP)
|
||||
RET
|
||||
|
||||
TEXT ·popcntMaskSliceAsm(SB),4,$0-56
|
||||
XORQ AX, AX
|
||||
MOVQ s_base+0(FP), SI
|
||||
MOVQ s_len+8(FP), CX
|
||||
TESTQ CX, CX
|
||||
JZ popcntMaskSliceEnd
|
||||
MOVQ m+24(FP), DI
|
||||
popcntMaskSliceLoop:
|
||||
MOVQ (DI), DX
|
||||
NOTQ DX
|
||||
ANDQ (SI), DX
|
||||
POPCNTQ_DX_DX
|
||||
ADDQ DX, AX
|
||||
ADDQ $8, SI
|
||||
ADDQ $8, DI
|
||||
LOOP popcntMaskSliceLoop
|
||||
popcntMaskSliceEnd:
|
||||
MOVQ AX, ret+48(FP)
|
||||
RET
|
||||
|
||||
TEXT ·popcntAndSliceAsm(SB),4,$0-56
|
||||
XORQ AX, AX
|
||||
MOVQ s_base+0(FP), SI
|
||||
MOVQ s_len+8(FP), CX
|
||||
TESTQ CX, CX
|
||||
JZ popcntAndSliceEnd
|
||||
MOVQ m+24(FP), DI
|
||||
popcntAndSliceLoop:
|
||||
MOVQ (DI), DX
|
||||
ANDQ (SI), DX
|
||||
POPCNTQ_DX_DX
|
||||
ADDQ DX, AX
|
||||
ADDQ $8, SI
|
||||
ADDQ $8, DI
|
||||
LOOP popcntAndSliceLoop
|
||||
popcntAndSliceEnd:
|
||||
MOVQ AX, ret+48(FP)
|
||||
RET
|
||||
|
||||
TEXT ·popcntOrSliceAsm(SB),4,$0-56
|
||||
XORQ AX, AX
|
||||
MOVQ s_base+0(FP), SI
|
||||
MOVQ s_len+8(FP), CX
|
||||
TESTQ CX, CX
|
||||
JZ popcntOrSliceEnd
|
||||
MOVQ m+24(FP), DI
|
||||
popcntOrSliceLoop:
|
||||
MOVQ (DI), DX
|
||||
ORQ (SI), DX
|
||||
POPCNTQ_DX_DX
|
||||
ADDQ DX, AX
|
||||
ADDQ $8, SI
|
||||
ADDQ $8, DI
|
||||
LOOP popcntOrSliceLoop
|
||||
popcntOrSliceEnd:
|
||||
MOVQ AX, ret+48(FP)
|
||||
RET
|
||||
|
||||
TEXT ·popcntXorSliceAsm(SB),4,$0-56
|
||||
XORQ AX, AX
|
||||
MOVQ s_base+0(FP), SI
|
||||
MOVQ s_len+8(FP), CX
|
||||
TESTQ CX, CX
|
||||
JZ popcntXorSliceEnd
|
||||
MOVQ m+24(FP), DI
|
||||
popcntXorSliceLoop:
|
||||
MOVQ (DI), DX
|
||||
XORQ (SI), DX
|
||||
POPCNTQ_DX_DX
|
||||
ADDQ DX, AX
|
||||
ADDQ $8, SI
|
||||
ADDQ $8, DI
|
||||
LOOP popcntXorSliceLoop
|
||||
popcntXorSliceEnd:
|
||||
MOVQ AX, ret+48(FP)
|
||||
RET
|
||||
|
||||
|
||||
TEXT ·popcntAsm(SB),4,$0-16
|
||||
MOVQ x+0(FP), DX
|
||||
POPCNTQ_DX_DX
|
||||
MOVQ DX, ret+8(FP)
|
||||
RET
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
// Copyright 2017 Pilosa Corp.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// +build amd64
|
||||
|
||||
package roaring
|
||||
|
||||
func hasAsm() bool
|
||||
|
||||
func BSFQ(memory uint64) int
|
||||
|
||||
func POPCNTQ(memory uint64) int
|
||||
|
||||
|
||||
//go:noescape
|
||||
var useAsm = hasAsm()
|
||||
|
||||
//go:noescape
|
||||
func popcntSliceAsm(s []uint64) uint64
|
||||
|
||||
//go:noescape
|
||||
func popcntMaskSliceAsm(s, m []uint64) uint64
|
||||
|
||||
//go:noescape
|
||||
func popcntAndSliceAsm(s, m []uint64) uint64
|
||||
|
||||
//go:noescape
|
||||
func popcntOrSliceAsm(s, m []uint64) uint64
|
||||
|
||||
//go:noescape
|
||||
func popcntXorSliceAsm(s, m []uint64) uint64
|
||||
|
||||
//go:noescape
|
||||
func popcntAsm(x uint64) uint64
|
||||
|
||||
func popcntSlice(s []uint64) uint64 {
|
||||
if useAsm {
|
||||
return popcntSliceAsm(s)
|
||||
}
|
||||
return popcntSliceGo(s)
|
||||
}
|
||||
|
||||
func popcntMaskSlice(s, m []uint64) uint64 {
|
||||
if useAsm {
|
||||
return popcntMaskSliceAsm(s, m)
|
||||
}
|
||||
return popcntMaskSliceGo(s, m)
|
||||
}
|
||||
|
||||
func popcntAndSlice(s, m []uint64) uint64 {
|
||||
if useAsm {
|
||||
return popcntAndSliceAsm(s, m)
|
||||
}
|
||||
return popcntAndSliceGo(s, m)
|
||||
}
|
||||
|
||||
func popcntOrSlice(s, m []uint64) uint64 {
|
||||
if useAsm {
|
||||
return popcntOrSliceAsm(s, m)
|
||||
}
|
||||
return popcntOrSliceGo(s, m)
|
||||
}
|
||||
|
||||
func popcntXorSlice(s, m []uint64) uint64 {
|
||||
if useAsm {
|
||||
return popcntXorSliceAsm(s, m)
|
||||
}
|
||||
return popcntXorSliceGo(s, m)
|
||||
}
|
||||
|
||||
func popcnt(x uint64) uint64 {
|
||||
if useAsm {
|
||||
return popcntAsm(x)
|
||||
}
|
||||
return popcntGo(x)
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
// Copyright 2017 Pilosa Corp.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// +build !amd64
|
||||
|
||||
package roaring
|
||||
|
||||
func hasAsm() bool {return false}
|
||||
|
||||
|
||||
func popcntSlice(s []uint64) uint64 { return popcntSliceGo(s) }
|
||||
func popcntMaskSlice(s, m []uint64) uint64 { return popcntMaskSliceGo(s, m) }
|
||||
func popcntAndSlice(s, m []uint64) uint64 { return popcntAndSliceGo(s, m) }
|
||||
func popcntOrSlice(s, m []uint64) uint64 { return popcntOrSliceGo(s, m) }
|
||||
func popcntXorSlice(s, m []uint64) uint64 { return popcntXorSliceGo(s, m) }
|
||||
func popcnt(s uint64) uint64 { return popcntGo(s) }
|
||||
|
|
@ -1,139 +0,0 @@
|
|||
// Copyright 2017 Pilosa Corp.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package roaring
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestBSFQ(t *testing.T) {
|
||||
result := BSFQ(2)
|
||||
if result != 1 {
|
||||
t.Fatalf("BSF INCORRECT: %d", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBSFQ_CompareGo(t *testing.T) {
|
||||
v := uint64(1)
|
||||
for i := 0; i < 64; i++ {
|
||||
if BSFQ(v) != trailingZeroN(v) {
|
||||
t.Fatalf("BSF INCORRECT: %d %d", BSFQ(v), trailingZeroN(v))
|
||||
}
|
||||
if v == 0 {
|
||||
v = 1
|
||||
} else {
|
||||
v *= 2
|
||||
}
|
||||
}
|
||||
/*
|
||||
if bsfq(0) != trailingZeroN(0) {
|
||||
fmt.Println(bsfq(0))
|
||||
t.Fatalf("BSF INCORRECT")
|
||||
}
|
||||
*/
|
||||
}
|
||||
func BenchmarkBSF(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
BSFQ(uint64(i))
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkTrailingZeroN(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
trailingZeroN(uint64(i))
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkPOPCNTQ(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
POPCNTQ(uint64(i))
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkPopcount(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
popcount(uint64(i))
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkPopcntAsm(b *testing.B) {
|
||||
// run the Fib function b.N times
|
||||
for n := 0; n < b.N; n++ {
|
||||
popcntAsm(0xdeadbeef)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkPopcntGo(b *testing.B) {
|
||||
// run the Fib function b.N times
|
||||
for n := 0; n < b.N; n++ {
|
||||
popcntGo(0xdeadbeef)
|
||||
}
|
||||
}
|
||||
|
||||
func getData() []uint64 {
|
||||
return []uint64{
|
||||
0xdeadbeef,
|
||||
0xdeadbeef,
|
||||
0xdeadbeef,
|
||||
0xdeadbeef,
|
||||
0xdeadbeef,
|
||||
0xdeadbeef,
|
||||
0xdeadbeef,
|
||||
0xdeadbeef,
|
||||
0xdeadbeef,
|
||||
0xdeadbeef,
|
||||
0xdeadbeef,
|
||||
0xdeadbeef,
|
||||
0xdeadbeef,
|
||||
0xdeadbeef,
|
||||
0xdeadbeef,
|
||||
0xdeadbeef,
|
||||
0xdeadbeef,
|
||||
0xdeadbeef,
|
||||
0xdeadbeef,
|
||||
0xdeadbeef,
|
||||
0xdeadbeef,
|
||||
0xdeadbeef,
|
||||
0xdeadbeef,
|
||||
0xdeadbeef,
|
||||
0xdeadbeef,
|
||||
0xdeadbeef,
|
||||
0xdeadbeef,
|
||||
0xdeadbeef,
|
||||
0xdeadbeef,
|
||||
0xdeadbeef,
|
||||
0xdeadbeef,
|
||||
0xdeadbeef,
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkPopcntSliceGo(b *testing.B) {
|
||||
d := getData()
|
||||
for n := 0; n < b.N; n++ {
|
||||
popcntSliceGo(d)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkPopcntSliceAsm(b *testing.B) {
|
||||
d := getData()
|
||||
for n := 0; n < b.N; n++ {
|
||||
popcntSliceAsm(d)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkPopcntSlice(b *testing.B) {
|
||||
d := getData()
|
||||
for n := 0; n < b.N; n++ {
|
||||
popcntSlice(d)
|
||||
}
|
||||
}
|
||||
|
|
@ -21,6 +21,7 @@ import (
|
|||
"fmt"
|
||||
"hash/fnv"
|
||||
"io"
|
||||
"math/bits"
|
||||
"sort"
|
||||
"unsafe"
|
||||
)
|
||||
|
|
@ -1274,10 +1275,10 @@ func (c *container) contains(v uint16) bool {
|
|||
func (c *container) bitmapCountRuns() (r int) {
|
||||
for i := 0; i < 1023; i++ {
|
||||
v, v1 := c.bitmap[i], c.bitmap[i+1]
|
||||
r = r + int(popcnt((v<<1)&^v)+((v>>63)&^v1))
|
||||
r = r + int(popcount((v<<1)&^v)+((v>>63)&^v1))
|
||||
}
|
||||
vl := c.bitmap[len(c.bitmap)-1]
|
||||
r = r + int(popcnt((vl<<1)&^vl)+vl>>63)
|
||||
r = r + int(popcount((vl<<1)&^vl)+vl>>63)
|
||||
return r
|
||||
}
|
||||
|
||||
|
|
@ -1918,7 +1919,7 @@ func intersectionCountArrayBitmap(a, b *container) (n int) {
|
|||
}
|
||||
|
||||
func intersectionCountBitmapBitmap(a, b *container) (n int) {
|
||||
return int(popcntAndSlice(a.bitmap, b.bitmap))
|
||||
return int(popcountAndSlice(a.bitmap, b.bitmap))
|
||||
}
|
||||
|
||||
func intersect(a, b *container) *container {
|
||||
|
|
@ -2061,22 +2062,22 @@ func intersectBitmapRun(a, b *container) *container {
|
|||
for valast >= vb.start && vastart <= vb.last && i < bitmapN {
|
||||
if vastart >= vb.start && valast <= vb.last { // a within b
|
||||
output.bitmap[i] = a.bitmap[i]
|
||||
output.n += int(popcnt(a.bitmap[i]))
|
||||
output.n += int(popcount(a.bitmap[i]))
|
||||
} else if vb.start >= vastart && vb.last <= valast { // b within a
|
||||
var mask uint64 = ((1 << (vb.last - vb.start + 1)) - 1) << (vb.start - vastart)
|
||||
bits := a.bitmap[i] & mask
|
||||
output.bitmap[i] |= bits
|
||||
output.n += int(popcnt(bits))
|
||||
output.n += int(popcount(bits))
|
||||
} else if vastart < vb.start { // a overlaps front of b
|
||||
offset := 64 - (1 + valast - vb.start)
|
||||
bits := (a.bitmap[i] >> offset) << offset
|
||||
output.bitmap[i] |= bits
|
||||
output.n += int(popcnt(bits))
|
||||
output.n += int(popcount(bits))
|
||||
} else if vb.start < vastart { // b overlaps front of a
|
||||
offset := 64 - (1 + vb.last - vastart)
|
||||
bits := (a.bitmap[i] << offset) >> offset
|
||||
output.bitmap[i] |= bits
|
||||
output.n += int(popcnt(bits))
|
||||
output.n += int(popcount(bits))
|
||||
}
|
||||
// update loop vars
|
||||
i++
|
||||
|
|
@ -2293,19 +2294,19 @@ func (c *container) bitmapSetRange(i, j uint64) {
|
|||
y := (j - 1) >> 6
|
||||
var X uint64 = maxBitmap << (i % 64)
|
||||
var Y uint64 = maxBitmap >> (63 - ((j - 1) % 64))
|
||||
xcnt := popcnt(X)
|
||||
ycnt := popcnt(Y)
|
||||
xcnt := popcount(X)
|
||||
ycnt := popcount(Y)
|
||||
if x == y {
|
||||
c.n += int((j - i) - popcnt(c.bitmap[x]&(X&Y)))
|
||||
c.n += int((j - i) - popcount(c.bitmap[x]&(X&Y)))
|
||||
c.bitmap[x] |= (X & Y)
|
||||
} else {
|
||||
c.n += int(xcnt - popcnt(c.bitmap[x]&X))
|
||||
c.n += int(xcnt - popcount(c.bitmap[x]&X))
|
||||
c.bitmap[x] |= X
|
||||
for i := x + 1; i < y; i++ {
|
||||
c.n += int(64 - popcnt(c.bitmap[i]))
|
||||
c.n += int(64 - popcount(c.bitmap[i]))
|
||||
c.bitmap[i] = maxBitmap
|
||||
}
|
||||
c.n += int(ycnt - popcnt(c.bitmap[y]&Y))
|
||||
c.n += int(ycnt - popcount(c.bitmap[y]&Y))
|
||||
c.bitmap[y] |= Y
|
||||
}
|
||||
}
|
||||
|
|
@ -2317,21 +2318,21 @@ func (c *container) bitmapXorRange(i, j uint64) {
|
|||
var X uint64 = maxBitmap << (i % 64)
|
||||
var Y uint64 = maxBitmap >> (63 - ((j - 1) % 64))
|
||||
if x == y {
|
||||
cnt := popcnt(c.bitmap[x])
|
||||
cnt := popcount(c.bitmap[x])
|
||||
c.bitmap[x] ^= (X & Y) //// flip
|
||||
c.n += int(popcnt(c.bitmap[x]) - cnt)
|
||||
c.n += int(popcount(c.bitmap[x]) - cnt)
|
||||
} else {
|
||||
cnt := popcnt(c.bitmap[x])
|
||||
cnt := popcount(c.bitmap[x])
|
||||
c.bitmap[x] ^= X
|
||||
c.n += int(popcnt(c.bitmap[x]) - cnt)
|
||||
c.n += int(popcount(c.bitmap[x]) - cnt)
|
||||
for i := x + 1; i < y; i++ {
|
||||
cnt = popcnt(c.bitmap[i])
|
||||
cnt = popcount(c.bitmap[i])
|
||||
c.bitmap[i] ^= maxBitmap
|
||||
c.n += int(popcnt(c.bitmap[i]) - cnt)
|
||||
c.n += int(popcount(c.bitmap[i]) - cnt)
|
||||
}
|
||||
cnt = popcnt(c.bitmap[y])
|
||||
cnt = popcount(c.bitmap[y])
|
||||
c.bitmap[y] ^= Y
|
||||
c.n += int(popcnt(c.bitmap[y]) - cnt)
|
||||
c.n += int(popcount(c.bitmap[y]) - cnt)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2342,16 +2343,16 @@ func (c *container) bitmapZeroRange(i, j uint64) {
|
|||
var X uint64 = maxBitmap << (i % 64)
|
||||
var Y uint64 = maxBitmap >> (63 - ((j - 1) % 64))
|
||||
if x == y {
|
||||
c.n -= int(popcnt(c.bitmap[x] & (X & Y)))
|
||||
c.n -= int(popcount(c.bitmap[x] & (X & Y)))
|
||||
c.bitmap[x] &= ^(X & Y)
|
||||
} else {
|
||||
c.n -= int(popcnt(c.bitmap[x] & X))
|
||||
c.n -= int(popcount(c.bitmap[x] & X))
|
||||
c.bitmap[x] &= ^X
|
||||
for i := x + 1; i < y; i++ {
|
||||
c.n -= int(popcnt(c.bitmap[i]))
|
||||
c.n -= int(popcount(c.bitmap[i]))
|
||||
c.bitmap[i] = 0
|
||||
}
|
||||
c.n -= int(popcnt(c.bitmap[y] & Y))
|
||||
c.n -= int(popcount(c.bitmap[y] & Y))
|
||||
c.bitmap[y] &= ^Y
|
||||
}
|
||||
}
|
||||
|
|
@ -2376,7 +2377,7 @@ func unionBitmapBitmap(a, b *container) *container {
|
|||
for i := 0; i < bitmapN; i++ {
|
||||
v := a.bitmap[i] | b.bitmap[i]
|
||||
output.bitmap[i] = v
|
||||
output.n += int(popcnt(v))
|
||||
output.n += int(popcount(v))
|
||||
}
|
||||
|
||||
return output
|
||||
|
|
@ -2812,7 +2813,7 @@ func xorBitmapBitmap(a, b *container) *container {
|
|||
for i := 0; i < bitmapN; i++ {
|
||||
v := a.bitmap[i] ^ b.bitmap[i]
|
||||
output.bitmap[i] = v
|
||||
output.n += int(popcnt(v))
|
||||
output.n += int(popcount(v))
|
||||
}
|
||||
|
||||
if output.count() < ArrayMaxSize {
|
||||
|
|
@ -2975,35 +2976,7 @@ func search64(a []uint64, value uint64) int {
|
|||
// trailingZeroN returns the number of trailing zeros in v.
|
||||
// v must be greater than zero.
|
||||
func trailingZeroN(v uint64) int {
|
||||
n := int64(63)
|
||||
if y := v << 32; y != 0 {
|
||||
n, v = n-32, y
|
||||
}
|
||||
if y := v << 16; y != 0 {
|
||||
n, v = n-16, y
|
||||
}
|
||||
if y := v << 8; y != 0 {
|
||||
n, v = n-8, y
|
||||
}
|
||||
if y := v << 4; y != 0 {
|
||||
n, v = n-4, y
|
||||
}
|
||||
if y := v << 2; y != 0 {
|
||||
n, v = n-2, y
|
||||
}
|
||||
return int(n - int64(v<<1>>63))
|
||||
}
|
||||
|
||||
// bit population count, taken from
|
||||
// https://code.google.com/p/go/issues/detail?id=4988#c11
|
||||
// credit: https://code.google.com/u/arnehormann/
|
||||
func popcount(x uint64) (n uint64) {
|
||||
x -= (x >> 1) & 0x5555555555555555
|
||||
x = (x>>2)&0x3333333333333333 + x&0x3333333333333333
|
||||
x += x >> 4
|
||||
x &= 0x0f0f0f0f0f0f0f0f
|
||||
x *= 0x0101010101010101
|
||||
return x >> 56
|
||||
return bits.TrailingZeros64(v)
|
||||
}
|
||||
|
||||
// ErrorList represents a list of errors.
|
||||
|
|
@ -3265,3 +3238,47 @@ func xorBitmapRun(a, b *container) *container {
|
|||
}
|
||||
return output
|
||||
}
|
||||
|
||||
func popcount(x uint64) uint64 {
|
||||
return uint64(bits.OnesCount64(x))
|
||||
}
|
||||
|
||||
func popcountSlice(s []uint64) uint64 {
|
||||
cnt := uint64(0)
|
||||
for _, x := range s {
|
||||
cnt += popcount(x)
|
||||
}
|
||||
return cnt
|
||||
}
|
||||
|
||||
func popcountMaskSlice(s, m []uint64) uint64 {
|
||||
cnt := uint64(0)
|
||||
for i := range s {
|
||||
cnt += popcount(s[i] &^ m[i])
|
||||
}
|
||||
return cnt
|
||||
}
|
||||
|
||||
func popcountAndSlice(s, m []uint64) uint64 {
|
||||
cnt := uint64(0)
|
||||
for i := range s {
|
||||
cnt += popcount(s[i] & m[i])
|
||||
}
|
||||
return cnt
|
||||
}
|
||||
|
||||
func popcountOrSlice(s, m []uint64) uint64 {
|
||||
cnt := uint64(0)
|
||||
for i := range s {
|
||||
cnt += popcount(s[i] | m[i])
|
||||
}
|
||||
return cnt
|
||||
}
|
||||
|
||||
func popcountXorSlice(s, m []uint64) uint64 {
|
||||
cnt := uint64(0)
|
||||
for i := range s {
|
||||
cnt += popcount(s[i] ^ m[i])
|
||||
}
|
||||
return cnt
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue