add bitmapCountRuns and arrayCountRuns

This commit is contained in:
Matt Jaffee 2017-05-31 21:10:06 -05:00
parent dbee584866
commit 1a8780c4a2
2 changed files with 112 additions and 0 deletions

View file

@ -1164,6 +1164,27 @@ func (c *container) contains(v uint32) 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))
}
vl := c.bitmap[len(c.bitmap)-1]
r = r + int(popcnt((vl<<1)&^vl)+vl>>63)
return r
}
func (c *container) arrayCountRuns() (r int) {
prev := -2
for _, v := range c.array {
if uint32(prev+1) != v {
r += 1
}
prev = int(v)
}
return r
}
func (c *container) arrayContains(v uint32) bool {
return search32(c.array, v) >= 0
}

View file

@ -872,3 +872,94 @@ func TestRunToArray(t *testing.T) {
}
}
}
func TestBitmapCountRuns(t *testing.T) {
c := &container{bitmap: make([]uint64, bitmapN)}
tests := []struct {
bitmap []uint64
exp int
}{
{
bitmap: []uint64{0xFF00FF00},
exp: 2,
},
{
bitmap: []uint64{0xFF00FF0000000000, 0x1},
exp: 2,
},
{
bitmap: []uint64{0xFF00FF0000000000, 0x2, 0x100},
exp: 4,
},
{
bitmap: []uint64{0xFF00FF0000000000, 0x1010101FF0101010, 0x100},
exp: 10,
},
}
for i, test := range tests {
for j, v := range test.bitmap {
c.bitmap[j] = v
}
ret := c.bitmapCountRuns()
if ret != test.exp {
t.Fatalf("test #%v expected %v but got %v", i, test.exp, ret)
}
for j, _ := range test.bitmap {
c.bitmap[j] = 0
}
}
test := tests[3]
for j, v := range test.bitmap {
c.bitmap[1024-len(test.bitmap)+j] = v
}
ret := c.bitmapCountRuns()
if ret != test.exp {
t.Fatalf("test at end expected %v but got %v", test.exp, ret)
}
}
func TestArrayCountRuns(t *testing.T) {
c := &container{}
tests := []struct {
array []uint32
exp int
}{
{
array: []uint32{},
exp: 0,
},
{
array: []uint32{0},
exp: 1,
},
{
array: []uint32{1},
exp: 1,
},
{
array: []uint32{1, 2, 3, 5},
exp: 2,
},
{
array: []uint32{0, 1, 3, 9, 2048, 4096, 4097, 65534, 65535},
exp: 6,
},
{
array: []uint32{0, 10, 11, 12},
exp: 2,
},
}
for i, test := range tests {
c.array = test.array
ret := c.arrayCountRuns()
if ret != test.exp {
t.Fatalf("test #%v expected %v but got %v", i, test.exp, ret)
}
}
}