Skip to content

Commit 49caae5

Browse files
authored
Merge pull request #481 from customerio/bit_slice_bulk
Add SetMany and SetBigMany support
2 parents 9239847 + 1d650c7 commit 49caae5

File tree

4 files changed

+72
-0
lines changed

4 files changed

+72
-0
lines changed

BitSliceIndexing/bsi.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,29 @@ func (b *BSI) SetValue(columnID uint64, value int64) {
113113
b.eBM.Add(uint32(columnID))
114114
}
115115

116+
// SetMany sets a value for foundSet
117+
func (b *BSI) SetMany(foundSet *roaring.Bitmap, value int64) {
118+
119+
// If max/min values are set to zero then automatically determine bit array size
120+
if b.MaxValue == 0 && b.MinValue == 0 {
121+
for i := bits.Len64(uint64(value)) - b.BitCount(); i > 0; i-- {
122+
b.bA = append(b.bA, roaring.NewBitmap())
123+
if b.runOptimized {
124+
b.bA[i].RunOptimize()
125+
}
126+
}
127+
}
128+
129+
for i := 0; i < b.BitCount(); i++ {
130+
if uint64(value)&(1<<uint64(i)) > 0 {
131+
b.bA[i].Or(foundSet)
132+
} else {
133+
b.bA[i].AndNot(foundSet)
134+
}
135+
}
136+
b.eBM.Or(foundSet)
137+
}
138+
116139
// GetValue gets the value at the column ID. Second param will be false for non-existent values.
117140
func (b *BSI) GetValue(columnID uint64) (int64, bool) {
118141
value := int64(0)

BitSliceIndexing/bsi_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,17 @@ func TestSetAndGet(t *testing.T) {
2424
assert.Equal(t, int64(8), gv)
2525
}
2626

27+
func TestSetMany(t *testing.T) {
28+
bsi := setup()
29+
// update with mix of existing and new columns
30+
upd := roaring.BitmapOf(30, 31, 32, 33, 34, 35, 101, 102, 103)
31+
bsi.SetMany(upd, 35)
32+
33+
matches := bsi.CompareValue(0, EQ, 35, 0, nil)
34+
35+
assert.True(t, upd.Equals(matches))
36+
}
37+
2738
func setup() *BSI {
2839

2940
bsi := NewBSI(100, 0)

roaring64/bsi64.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,37 @@ func (b *BSI) SetBigValue(columnID uint64, value *big.Int) {
115115
b.eBM.Add(columnID)
116116
}
117117

118+
func (b *BSI) SetBigMany(foundSet *Bitmap, value *big.Int) {
119+
// If max/min values are set to zero then automatically determine bit array size
120+
if b.MaxValue == 0 && b.MinValue == 0 {
121+
minBits := value.BitLen() + 1
122+
if minBits == 1 {
123+
minBits = 2
124+
}
125+
for len(b.bA) < minBits {
126+
b.bA = append(b.bA, Bitmap{})
127+
}
128+
}
129+
for i := b.BitCount(); i >= 0; i-- {
130+
if value.Bit(i) == 0 {
131+
b.bA[i].AndNot(foundSet)
132+
} else {
133+
b.bA[i].Or(foundSet)
134+
}
135+
}
136+
b.eBM.Or(foundSet)
137+
}
138+
118139
// SetValue sets a value for a given columnID.
119140
func (b *BSI) SetValue(columnID uint64, value int64) {
120141
b.SetBigValue(columnID, big.NewInt(value))
121142
}
122143

144+
// SetMany sets a value for all columns in foundSet
145+
func (b *BSI) SetMany(foundSet *Bitmap, value int64) {
146+
b.SetBigMany(foundSet, big.NewInt(value))
147+
}
148+
123149
// GetValue gets the value at the column ID. Second param will be false for non-existent values.
124150
func (b *BSI) GetValue(columnID uint64) (value int64, exists bool) {
125151
bv, exists := b.GetBigValue(columnID)

roaring64/bsi64_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,18 @@ func TestSetAndGetSimple(t *testing.T) {
3838
assert.Equal(t, int64(8), gv)
3939
}
4040

41+
func TestSetMany(t *testing.T) {
42+
bsi := setup()
43+
44+
upd := BitmapOf(30, 31, 32, 33, 34, 35, 101, 102, 103)
45+
// update many including existing columns
46+
bsi.SetMany(upd, 35)
47+
48+
matches := bsi.CompareValue(0, EQ, 35, 0, nil)
49+
50+
assert.True(t, upd.Equals(matches))
51+
}
52+
4153
func TestSetAndGetBigValue(t *testing.T) {
4254

4355
// Set a large UUID value---

0 commit comments

Comments
 (0)