@@ -1356,3 +1356,65 @@ func BenchmarkCardinalityInRange(b *testing.B) {
13561356 }
13571357 }
13581358}
1359+
1360+ // BenchmarkFastOrRunContainers measures FastOr over inputs containing
1361+ // runContainer16 slots (the shape AddRange and RunOptimize produce),
1362+ // exercising the runContainer16 -> bitmapContainer pre-promotion in
1363+ // (*Bitmap).lazyOR. See issue #81.
1364+ //
1365+ // go test -bench BenchmarkFastOrRunContainers -benchmem -run - -benchtime=2s
1366+ func BenchmarkFastOrRunContainers (b * testing.B ) {
1367+ const numBitmaps = 15
1368+ const blocksPerBitmap = 40 // each block = 1<<16 bits
1369+ const runsPerBlock = 8
1370+
1371+ rng := rand .New (rand .NewSource (42 ))
1372+ bms := make ([]* Bitmap , numBitmaps )
1373+ for i := 0 ; i < numBitmaps ; i ++ {
1374+ bm := NewBitmap ()
1375+ for blk := 0 ; blk < blocksPerBitmap ; blk ++ {
1376+ base := uint64 (blk ) << 16
1377+ offset := uint64 (rng .Intn (1000 ))
1378+ for r := 0 ; r < runsPerBlock ; r ++ {
1379+ start := base + offset + uint64 (r )* 8000 + uint64 (i * 37 )
1380+ end := start + 6000
1381+ blockEnd := base + (1 << 16 )
1382+ if end > blockEnd {
1383+ end = blockEnd
1384+ }
1385+ if start >= blockEnd {
1386+ break
1387+ }
1388+ bm .AddRange (start , end )
1389+ }
1390+ }
1391+ bm .RunOptimize ()
1392+ bms [i ] = bm
1393+ }
1394+
1395+ // Sanity-check: the workload must actually contain runContainer16,
1396+ // otherwise the bench wouldn't exercise the patched path.
1397+ hasRunContainer := false
1398+ for _ , bm := range bms {
1399+ for _ , c := range bm .highlowcontainer .containers {
1400+ if _ , ok := c .(* runContainer16 ); ok {
1401+ hasRunContainer = true
1402+ break
1403+ }
1404+ }
1405+ if hasRunContainer {
1406+ break
1407+ }
1408+ }
1409+ if ! hasRunContainer {
1410+ b .Fatalf ("workload did not produce any runContainer16; bench would not exercise the patched path" )
1411+ }
1412+
1413+ b .ResetTimer ()
1414+ for n := 0 ; n < b .N ; n ++ {
1415+ res := FastOr (bms ... )
1416+ if res .GetCardinality () == 0 {
1417+ b .Fatal ("unexpected empty result" )
1418+ }
1419+ }
1420+ }
0 commit comments