MCPcopy
hub / github.com/RoaringBitmap/roaring / CardinalityInRange

Method CardinalityInRange

roaring.go:1281–1346  ·  view source on GitHub ↗

CardinalityInRange returns the number of integers that are in the half-open range [start, end). It is equivalent to Rank(uint32(end-1)) - Rank(uint32(start-1)) for start > 0, but is optimized to only scan containers that overlap the range, making it O(k) in the number of containers spanned by [start

(start, end uint64)

Source from the content-addressed store, hash-verified

1279// in total containers. The parameter type is uint64 to allow end = 1<<32
1280// (the full 32-bit range).
1281func (rb *Bitmap) CardinalityInRange(start, end uint64) uint64 {
1282 if start >= end {
1283 return 0
1284 }
1285 if end > MaxUint32+1 {
1286 end = MaxUint32 + 1
1287 }
1288
1289 hbStart := highbits(uint32(start))
1290 hbEnd := highbits(uint32(end - 1)) // end-1 is the last included value
1291
1292 size := rb.highlowcontainer.size()
1293
1294 // Binary-search to find the first container index >= hbStart.
1295 startIdx := rb.highlowcontainer.getIndex(hbStart)
1296 if startIdx < 0 {
1297 startIdx = -startIdx - 1 // insertion point
1298 }
1299 if startIdx >= size {
1300 return 0
1301 }
1302
1303 result := uint64(0)
1304
1305 // Handle the case where start and end are in the same container.
1306 if hbStart == hbEnd {
1307 key := rb.highlowcontainer.getKeyAtIndex(startIdx)
1308 if key == hbStart {
1309 lo := uint(lowbits(uint32(start)))
1310 hi := uint(lowbits(uint32(end-1))) + 1
1311 return uint64(rb.highlowcontainer.getContainerAtIndex(startIdx).getCardinalityInRange(lo, hi))
1312 }
1313 return 0
1314 }
1315
1316 // Handle the first container (may be partial).
1317 key := rb.highlowcontainer.getKeyAtIndex(startIdx)
1318 if key == hbStart {
1319 lo := uint(lowbits(uint32(start)))
1320 result += uint64(rb.highlowcontainer.getContainerAtIndex(startIdx).getCardinalityInRange(lo, 1<<16))
1321 startIdx++
1322 }
1323
1324 // Binary-search to find the last container index <= hbEnd.
1325 endIdx := rb.highlowcontainer.getIndex(hbEnd)
1326 endPresent := endIdx >= 0
1327 if endIdx < 0 {
1328 endIdx = -endIdx - 2 // index of the last container with key < hbEnd
1329 }
1330
1331 // Tight loop over middle containers — no per-iteration key comparisons.
1332 for i := startIdx; i <= endIdx; i++ {
1333 if endPresent && i == endIdx {
1334 break // this is the end container, handled below
1335 }
1336 result += uint64(rb.highlowcontainer.getContainerAtIndex(i).getCardinality())
1337 }
1338

Calls 8

highbitsFunction · 0.70
lowbitsFunction · 0.70
getCardinalityInRangeMethod · 0.65
getCardinalityMethod · 0.65
sizeMethod · 0.45
getIndexMethod · 0.45
getKeyAtIndexMethod · 0.45
getContainerAtIndexMethod · 0.45