Skip to content

Commit ab3cee6

Browse files
committed
better fuzzer
1 parent 311bb0e commit ab3cee6

File tree

7 files changed

+480
-75
lines changed

7 files changed

+480
-75
lines changed

go.mod

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
module github.com/RoaringBitmap/roaring/v2
22

3-
go 1.22
3+
go 1.24.0
4+
5+
toolchain go1.24.4
46

57
require (
68
github.com/bits-and-blooms/bitset v1.24.1
@@ -11,6 +13,12 @@ require (
1113

1214
require (
1315
github.com/davecgh/go-spew v1.1.1 // indirect
16+
github.com/dvyukov/go-fuzz v0.0.0-20240924070022-e577bee5275c // indirect
17+
github.com/elazarl/go-bindata-assetfs v1.0.1 // indirect
1418
github.com/pmezard/go-difflib v1.0.0 // indirect
19+
github.com/stephens2424/writerset v1.0.2 // indirect
20+
golang.org/x/mod v0.29.0 // indirect
21+
golang.org/x/sync v0.17.0 // indirect
22+
golang.org/x/tools v0.38.0 // indirect
1523
gopkg.in/yaml.v3 v3.0.1 // indirect
1624
)

go.sum

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,32 @@
1+
github.com/Julusian/godocdown v0.0.0-20170816220326-6d19f8ff2df8/go.mod h1:INZr5t32rG59/5xeltqoCJoNY7e5x/3xoY9WSWVWg74=
12
github.com/bits-and-blooms/bitset v1.24.1 h1:hqnfFbjjk3pxGa5E9Ho3hjoU7odtUuNmJ9Ao+Bo8s1c=
23
github.com/bits-and-blooms/bitset v1.24.1/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
4+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
35
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
46
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
7+
github.com/dvyukov/go-fuzz v0.0.0-20240924070022-e577bee5275c h1:oLpHpHwNuAPvw3bBviEZNrJbigNNi5dRadfZnagGgZI=
8+
github.com/dvyukov/go-fuzz v0.0.0-20240924070022-e577bee5275c/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
9+
github.com/elazarl/go-bindata-assetfs v1.0.1 h1:m0kkaHRKEu7tUIUFVwhGGGYClXvyl4RE03qmvRTNfbw=
10+
github.com/elazarl/go-bindata-assetfs v1.0.1/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
511
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
612
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
713
github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM=
814
github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw=
915
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
1016
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
17+
github.com/robertkrimen/godocdown v0.0.0-20130622164427-0bfa04905481/go.mod h1:C9WhFzY47SzYBIvzFqSvHIR6ROgDo4TtdTuRaOMjF/s=
18+
github.com/stephens2424/writerset v1.0.2 h1:znRLgU6g8RS5euYRcy004XeE4W+Tu44kALzy7ghPif8=
19+
github.com/stephens2424/writerset v1.0.2/go.mod h1:aS2JhsMn6eA7e82oNmW4rfsgAOp9COBTTl8mzkwADnc=
20+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
21+
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
1122
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
1223
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
24+
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
25+
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
26+
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
27+
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
28+
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
29+
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
1330
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
1431
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
1532
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

roaring.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2145,6 +2145,34 @@ func (rb *Bitmap) Stats() Statistics {
21452145
return stats
21462146
}
21472147

2148+
// Describe prints a description of the bitmap's containers to stdout
2149+
func (rb *Bitmap) Describe() {
2150+
fmt.Printf("Bitmap with %d containers:\n", len(rb.highlowcontainer.containers))
2151+
for i, c := range rb.highlowcontainer.containers {
2152+
key := rb.highlowcontainer.keys[i]
2153+
shared := ""
2154+
if rb.highlowcontainer.needCopyOnWrite[i] {
2155+
shared = " (shared)"
2156+
}
2157+
switch c.(type) {
2158+
case *arrayContainer:
2159+
fmt.Printf(" Container %d (key %d): array, cardinality %d%s\n", i, key, c.getCardinality(), shared)
2160+
case *bitmapContainer:
2161+
fmt.Printf(" Container %d (key %d): bitmap, cardinality %d%s\n", i, key, c.getCardinality(), shared)
2162+
case *runContainer16:
2163+
fmt.Printf(" Container %d (key %d): run, cardinality %d%s\n", i, key, c.getCardinality(), shared)
2164+
default:
2165+
fmt.Printf(" Container %d (key %d): unknown type, cardinality %d%s\n", i, key, c.getCardinality(), shared)
2166+
}
2167+
}
2168+
valid := rb.Validate()
2169+
if valid != nil {
2170+
fmt.Printf(" Bitmap is INVALID: %v\n", valid)
2171+
} else {
2172+
fmt.Printf(" Bitmap is valid\n")
2173+
}
2174+
}
2175+
21482176
// Validate checks if the bitmap is internally consistent.
21492177
// You may call it after deserialization to check that the bitmap is valid.
21502178
// This function returns an error if the bitmap is invalid, nil otherwise.

roaring_test.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package roaring
22

33
import (
44
"bytes"
5+
"encoding/base64"
56
"fmt"
67
"math"
78
"math/rand"
@@ -15,6 +16,77 @@ import (
1516
"github.com/stretchr/testify/require"
1617
)
1718

19+
func TestFuzzerPanicRepro_1761171725501558000(t *testing.T) {
20+
b, _ := base64.StdEncoding.DecodeString("OzAAAAEPAAMAAQD1/wMA")
21+
bm := NewBitmap()
22+
bm.UnmarshalBinary(b)
23+
bm.Describe()
24+
b2, _ := base64.StdEncoding.DecodeString("OjAAAAEAAAAPAAEAEAAAAPb/9/8=")
25+
bm2 := NewBitmap()
26+
bm2.UnmarshalBinary(b2)
27+
bm2.Describe()
28+
bm.AndNot(bm2)
29+
}
30+
31+
func TestFuzzerRepro_1761171217612329001(t *testing.T) {
32+
b, _ := base64.StdEncoding.DecodeString("OzAAAAEPAAMAAQDo/wMA")
33+
bm := NewBitmap()
34+
bm.UnmarshalBinary(b)
35+
if err := bm.Validate(); err != nil {
36+
t.Errorf("Initial Validate failed: %v", err)
37+
}
38+
bm.Flip(uint64(1048555), uint64(1048555)+1)
39+
if err := bm.Validate(); err != nil {
40+
t.Errorf("Validate failed: %v", err)
41+
} else {
42+
t.Logf("Validate succeeded")
43+
}
44+
}
45+
46+
func TestFuzzerRepro_1761171217612329000(t *testing.T) {
47+
b, _ := base64.StdEncoding.DecodeString("OzAAAAEPAAMAAQDo/wMA")
48+
bm := NewBitmap()
49+
bm.UnmarshalBinary(b)
50+
if err := bm.Validate(); err != nil {
51+
t.Errorf("Initial Validate failed: %v", err)
52+
}
53+
bm.Flip(uint64(1048555), uint64(1048555)+1)
54+
if err := bm.Validate(); err != nil {
55+
t.Errorf("Validate failed: %v", err)
56+
} else {
57+
t.Logf("Validate succeeded")
58+
}
59+
}
60+
61+
func TestFuzzerRepro_1761171056770369000(t *testing.T) {
62+
b, _ := base64.StdEncoding.DecodeString("OzAAAAEAAAMAAQACAAMA")
63+
bm := NewBitmap()
64+
bm.UnmarshalBinary(b)
65+
if err := bm.Validate(); err != nil {
66+
t.Errorf("Initial Validate failed: %v", err)
67+
}
68+
bm.Remove(3)
69+
if err := bm.Validate(); err != nil {
70+
t.Errorf("Validate failed: %v", err)
71+
} else {
72+
t.Logf("Validate succeeded")
73+
}
74+
}
75+
func TestFuzzerRepro_1761170740641699000(t *testing.T) {
76+
b, _ := base64.StdEncoding.DecodeString("OzAAAAEAAAMAAQA2AAMA")
77+
bm := NewBitmap()
78+
bm.UnmarshalBinary(b)
79+
if err := bm.Validate(); err != nil {
80+
t.Errorf("Initial Validate failed: %v", err)
81+
}
82+
bm.AddInt(112)
83+
if err := bm.Validate(); err != nil {
84+
t.Errorf("Validate failed: %v", err)
85+
} else {
86+
t.Logf("Validate succeeded")
87+
}
88+
}
89+
1890
var bm1Arr = []uint32{279981785, 279982923, 279988809, 279995913}
1991

2092
const bm2Bytes = "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uQcAbrkBAHO5FACJuQIAjbkAAJC5AwCVuQMAmrkAAJy5AgChuQMAqLkHALG5AAC0uQIAuLkHAMO5JQDquQIA8LkXAAm6AAALugkAFroDABu6BQAiugIAKLoIADS6AQA3ugUAProKAEq6AQBNugAAULoJAFy6AQBfugUAZroKAHK6AgB6ugAAfLoUAJK6AgCYugcAoboAAKS6FAC6ugEAvboAAL+6BQDGugEAyboBAMy6BwDVug8A5roAAOi6CADyug0AAbsBAAS7DgAUuxcALbsAADC7BAA2uwIAO7sCAEC7GwBduykAiLsqALS7gwA5vFAAi7wEAJG8JAC3vEIA+7wGAAO9EAAVvQUAHL0SADC9CgA8vTIAcL0KAHy9AQB/vRcAmL0TAK29GwDKvVoAJr4iAEq+DABYvlcCscDiAJXBeAAPwh0ALsInAFfCEABpwgQAb8IJAHrCBwCDwgUAisIRAJ3CEgCxwgQAt8IYANHCEADjwgcA7cIAAPDCKwAdwx8APsMAAEDDSACKwwMAj8MWAKfDCgCzwzMA6MP8AObEcABYxQEAW8UEAGHFDABvxQUAdsUQAIjFDQCXxQ0ApsUYAMDFAADCxSEA5cUAAOfFCgDzxQkA/sUFAAXGBQAMxgcAFcYNACTGKwBRxjIAhcYEAIvGNQDCxmwAMMfSAATIXQBjyAMAaMgVAH/IFwCYyCYAwMgGAMjICwDVyA4A5cggAAfJCAARyRcAKskSAD7JAQBByQoATckXAGbJGgCCyQAAhMkLAJLJFQCpyRMAvskEAMTJWAEeywAAIMsnAEnLAQBMyw8AXcsUAHPLLQCiyw8As8sAALXLAAC4yxoA1MsmAP3LAgABzCsAL8x8AK3MGADHzAMAzMwLANnMCwDnzBcAAM0QABLNGQAtzQoAOc0GAEHNEQBUzQkAX80TAHXNFQCMzQoAmc1JAOXNDADzzScAHM4qAEjOiwDVzgQA284NAOrOdwJj0Q0ActEBAHXRTQDE0QcAzdFQAB/SEAAx0joBbdOhABDUJwA51HMArtSSAELV6gAu1gcAN9YYAFHWIwB21gMAe9YAAH3WAwCC1hsAn9YKAKvWAQCu1gcAt9YBALrWBwDD1gEAxtYJANLWGwDv1gIA89YAAPXWFwAO1wAAENcCABTXFgAs1zoAaNdBAKvXnwBM2AEAT9gGAFfYJwCA2HkA+9idAJrZGgC22QEBudoVANDaOQAL22wAedu8ADfcLABl3CYAjdwcAKvcFgDD3EwAEd1fAHLdTQDB3R8A4t0fAAPenACh3jEA1N4SAOjehQBv3wAAcd9AALPfAQC23xsA098zAAjgEgAc4AIAIOADACXgBQAs4AAAL+ADADTgBAA64AAAPOAKAEjgCQBT4AcAXOAHAGXgHQCE4AAAhuAKAJLgFQCp4A0AuOAkAN7gAwDk4A4A9OAlABvhGQA24RcAT+ECAFPhGABt4QAAb+EbAIzhCwCZ4QUAoOEGAKjhFwDB4QAAw+EBAMbhDgDW4QsA4+EdAALiAwAH4gsAFOIDABniIgA94gEAQOIhAGPiEAB14i0ApOISALjiFADO4gwA3OITAPHiAQD04gYA/OIZABfjAQAa4wIAHuMBACHjBgAp4wQAL+MKADvjDABJ4wwAV+MOAGfjBQBu4wEAceMAAHPjBQB64woAhuMBAInjBwCT4w4Ao+MIAK3jAgCx4wcAuuMDAL/jCgDL4wAAzeMAAM/jBADW4wMA2+MEAOHjBADn4woA8+MCAPfjBQD+4wIAA+QEAArkEAAc5AAAIuQEACjkCgA05AAAOOQDAD7kDABM5AAATuQAAFDkAwBW5AMAW+QEAGHkBQBo5AoAdOQAAHjkAwB+5AwAjOQAAJDkAwCV5AQAnOQGAKTkAQCn5AQAreQDALTkCgDA5AkAy+QEANHkBQDY5AcA4eQHAOrkAgDu5AAA8OQCAPTkBgD85A4ADOUDABHlDQAg5TMAVeUdAHTlBAB65QIAfuUQAJDlFgCo5RAAuuUIAMTlCQDP5SsA/OUdABvmCQAm5hoAQuYSAFbmHAB05ikAn+YSALTmLgDl5g0A9OYxACfnAQAq5wIALuc+AG7nDgF+6BQAlOguAMToqQBv6QwAfekaAJnphwAj6rEA1uoeAPbqTwBH64YAz+sIANnrPgAZ7CYAQewnAGrsBABw7BwAjuwCAJLsCwCf7AIAo+xGAOvsNAAh7QAAI+07AGDtBQBn7S0Alu0GAJ7tLwDP7RYA5+0MAPXtJgAd7iIAQe4BAETuEQBY7g0AZ+4NAHbuLACk7jIA2O4UAO7uJgAW7xIAKu8zAF/vcQDS7yUA+e8RAA3wAgAR8BIAJfAqAFHwBABX8BAAafAfAIrwAQCN8BIAofALAK7wIwDT8A0A4vAHAOvwEgD/8AUABvETABvxCwAp8TsAZvEwAJjxHgC48QAAuvEiAN7xAwDj8Q0A8vEDAPfxBwAA8hsAHfISADHyBAA38hMATfIGAFXyEgBp8j4AqfICAK3yTgD98hsAGvNqAIbzCgCS8xMAp/MAAKrzAwCv8wkAuvMBAL7zAADA8wEAw/MBAMbzBQDN8wAA0fMAANTzAgDY8wEA2/MIAOXzAADn8wYA7/MAAPLzAwD38wMA/PMEAAT0AQAH9A0AGPQGACD0BgAo9AAALPQBAC/0AwA09AcAQPQDAEj0BgBQ9AEAU/QGAFv0CABn9AAAafQEAG/0AQB09AUAe/QEAIH0AQCF9AIAifQCAI/0AACS9AQAmPQCAJz0DgCt9AIAsfQFALj0AAC69AQAwvQEAMj0AgDM9AMA0fQCANb0AQDZ9AQA3/QBAOT0BQDr9AcA9PQHAP70AgAD9QEABvUCAAr1EQAf9Q8AMPUDADf1BAA99QUARPUGAE31AgBR9QYAWfULAGb1AQBq9RIAfvUNAI31BACV9Q8ApvUDAKz1AwCx9QYAufUGAMH1DADP9QkA2vUBAN31EADw9QMA9fUCAPn1AQD99QkACPYAAAr2BwAT9gYAG/YGACP2AAAl9gQAK/YCADD2AAAy9gcAO/YGAET2AABG9gMAS/YAAE32AwBS9gMAV/YIAGL2AABk9hEAd/YDAHz2AAB+9gMAg/YFAIr2BgCS9gEAlvYAAJj2EQCr9gEArvYHALj2AAC69gYAwvYNANH2DADg9gsA7fYBAPD2AgD09gAA9vYBAPn2AQD89goACPcDAA33CgAZ9wEAHPcBAB/3AQAi9wsAL/cCADP3AAA29wwARPcBAEf3AQBK9wwAWPcBAFv3AQBe9wkAafcAAGv3BABy9wkAffcAAH/3DACN9wEAkPcEAJb3CQCh9wAApPcDAKn3DAC39xAAyfcBAMz3EQDf9xIA9PcYAA74AAAQ+AsAHvgGACf4EQA8+AQAQvgOAFL4AABU+BYAbfgBAHD4DgCA+AsAjfgRAKD4AwCm+BEAuvgmAOL4FAD4+BQADvkJABr5CgAm+UIAavmEAPD5CwD9+TYANfoJAEH6LQBw+i0An/oLAKz6PwDt+hoACft4AIP7BgCL+xMBoPwYALr8UwAP/RIAI/0KAC/9BwA4/QkAQ/0kAGn9HgCJ/RsApv2yAFr+AQBd/gIAYf4IAGv+CgB3/gAAef5oAOP+EAD1/mIAWf+CAN3/BwDm/xkA"

roaringarray.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ func rangeOfOnes(start, last int) container {
108108
if last < 0 {
109109
panic("rangeOfOnes called with last < 0")
110110
}
111-
return newRunContainer16Range(uint16(start), uint16(last))
111+
return newRunContainer16Range(uint16(start), uint16(last)).toEfficientContainer()
112112
}
113113

114114
type roaringArray struct {

runcontainer.go

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1949,7 +1949,7 @@ func (rc *runContainer16) andNot(a container) container {
19491949
case *bitmapContainer:
19501950
return rc.andNotBitmap(c)
19511951
case *runContainer16:
1952-
return rc.andNotRunContainer16(c)
1952+
return rc.andNotRunContainer16(c).toEfficientContainer()
19531953
}
19541954
panic("unsupported container type")
19551955
}
@@ -2110,7 +2110,7 @@ func (rc *runContainer16) equals(o container) bool {
21102110

21112111
func (rc *runContainer16) iaddReturnMinimized(x uint16) container {
21122112
rc.Add(x)
2113-
return rc
2113+
return rc.toEfficientContainer()
21142114
}
21152115

21162116
func (rc *runContainer16) iadd(x uint16) (wasNew bool) {
@@ -2119,7 +2119,7 @@ func (rc *runContainer16) iadd(x uint16) (wasNew bool) {
21192119

21202120
func (rc *runContainer16) iremoveReturnMinimized(x uint16) container {
21212121
rc.removeKey(x)
2122-
return rc
2122+
return rc.toEfficientContainer()
21232123
}
21242124

21252125
func (rc *runContainer16) iremove(x uint16) bool {
@@ -2379,7 +2379,7 @@ func (rc *runContainer16) xor(a container) container {
23792379
case *bitmapContainer:
23802380
return rc.xorBitmap(c)
23812381
case *runContainer16:
2382-
return rc.xorRunContainer16(c)
2382+
return rc.xorRunContainer16(c).toEfficientContainer()
23832383
}
23842384
panic("unsupported container type")
23852385
}
@@ -2391,7 +2391,7 @@ func (rc *runContainer16) iandNot(a container) container {
23912391
case *bitmapContainer:
23922392
return rc.iandNotBitmap(c)
23932393
case *runContainer16:
2394-
return rc.iandNotRunContainer16(c)
2394+
return rc.iandNotRunContainer16(c).toEfficientContainer()
23952395
}
23962396
panic("unsupported container type")
23972397
}
@@ -2406,7 +2406,7 @@ func (rc *runContainer16) inot(firstOfRange, endx int) container {
24062406
}
24072407
// TODO: minimize copies, do it all inplace; not() makes a copy.
24082408
rc = rc.Not(firstOfRange, endx)
2409-
return rc
2409+
return rc.toEfficientContainer()
24102410
}
24112411

24122412
func (rc *runContainer16) rank(x uint16) int {
@@ -2480,21 +2480,23 @@ func (rc *runContainer16) iandNotArray(ac *arrayContainer) container {
24802480
rcb := rc.toBitmapContainer()
24812481
acb := ac.toBitmapContainer()
24822482
rcb.iandNotBitmapSurely(acb)
2483-
// TODO: check size and optimize the return value
2484-
// TODO: is inplace modification really required? If not, elide the copy.
2485-
rc2 := newRunContainer16FromBitmapContainer(rcb)
2486-
*rc = *rc2
2487-
return rc
2483+
answer := rcb.toEfficientContainer()
2484+
if runrc, ok := answer.(*runContainer16); ok {
2485+
*rc = *runrc
2486+
return rc
2487+
}
2488+
return answer
24882489
}
24892490

24902491
func (rc *runContainer16) iandNotBitmap(bc *bitmapContainer) container {
24912492
rcb := rc.toBitmapContainer()
24922493
rcb.iandNotBitmapSurely(bc)
2493-
// TODO: check size and optimize the return value
2494-
// TODO: is inplace modification really required? If not, elide the copy.
2495-
rc2 := newRunContainer16FromBitmapContainer(rcb)
2496-
*rc = *rc2
2497-
return rc
2494+
answer := rcb.toEfficientContainer()
2495+
if runrc, ok := answer.(*runContainer16); ok {
2496+
*rc = *runrc
2497+
return rc
2498+
}
2499+
return answer
24982500
}
24992501

25002502
func (rc *runContainer16) xorRunContainer16(x2 *runContainer16) container {

0 commit comments

Comments
 (0)