///|
/// Compact summary of the numeric extent of a bitmap.
pub(all) struct BitmapProfile {
cardinality : Int
minimum : Int?
maximum : Int?
span : Int
block_count : Int
}
///|
/// Inspect cardinality and extent without exposing container internals.
pub fn RoaringBitmap::profile(self : RoaringBitmap) -> BitmapProfile {
let minimum = self.minimum()
let maximum = self.maximum()
let span = match (minimum, maximum) {
(Some(start), Some(end)) => end - start + 1
_ => 0
}
{
cardinality: self.cardinality(),
minimum,
maximum,
span,
block_count: self.stats().block_count,
}
}
///|
/// Return numerator and denominator for exact Jaccard similarity.
/// Callers can choose their own floating-point representation if required.
pub fn RoaringBitmap::jaccard_parts(
self : RoaringBitmap,
other : RoaringBitmap,
) -> (Int, Int) {
(self.intersection(other).cardinality(), self.union(other).cardinality())
}
///|
/// Return a stable, evenly distributed sample in ascending order.
pub fn RoaringBitmap::sample_evenly(
self : RoaringBitmap,
count : Int,
) -> Array[Int] {
let output : Array[Int] = []
let total = self.cardinality()
if count <= 0 || total == 0 {
return output
}
let actual = if count < total { count } else { total }
for index in 0.. output.push(value)
None => ()
}
}
output
}
///|
/// Select the value at an exact rational quantile in `[0, denominator]`.
pub fn RoaringBitmap::quantile(
self : RoaringBitmap,
numerator : Int,
denominator : Int,
) -> Result[Int?, RoaringError] {
if denominator <= 0 || numerator < 0 || numerator > denominator {
return Err(InvalidRange(numerator, denominator))
}
let total = self.cardinality()
if total == 0 {
return Ok(None)
}
Ok(self.select(numerator * (total - 1) / denominator))
}
///|
/// Return exact intersection, left-only, right-only, and union cardinalities.
pub fn RoaringBitmap::overlap_parts(
self : RoaringBitmap,
other : RoaringBitmap,
) -> (Int, Int, Int, Int) {
let common = self.intersection(other).cardinality()
let left_only = self.cardinality() - common
let right_only = other.cardinality() - common
(common, left_only, right_only, common + left_only + right_only)
}
///|
/// Return occupied and total positions in the bitmap's inclusive numeric span.
pub fn RoaringBitmap::density_parts(self : RoaringBitmap) -> (Int, Int) {
let profile = self.profile()
(profile.cardinality, profile.span)
}
///|
/// Sample each `stride`th ordinal. Non-positive strides return an empty sample.
pub fn RoaringBitmap::sample_stride(
self : RoaringBitmap,
stride : Int,
) -> Array[Int] {
let output : Array[Int] = []
if stride <= 0 {
return output
}
let mut index = 0
while index < self.cardinality() {
match self.select(index) {
Some(value) => output.push(value)
None => ()
}
index += stride
}
output
}