///|
pub fn ShardedFuseFilter::build(
hashes : Array[Int],
shard_count : Int,
) -> Result[ShardedFuseFilter, FuseError] {
ShardedFuseFilter::build_with_options(
hashes,
shard_count,
default_build_options(),
)
}
///|
pub fn ShardedFuseFilter::build_with_options(
hashes : Array[Int],
shard_count : Int,
options : BuildOptions,
) -> Result[ShardedFuseFilter, FuseError] {
if shard_count <= 0 {
return Err(InvalidShardCount(shard_count))
}
match validate_input(hashes, options) {
Err(error) => return Err(error)
Ok(_) => ()
}
let buckets : Array[Array[Int]] = []
for _ in 0.. shards.push(Some(filter))
Err(error) => return Err(error)
}
}
}
Ok({ shard_count, shards })
}
///|
pub fn ShardedFuseFilter::contains(
self : ShardedFuseFilter,
hash : Int,
) -> Bool {
if hash < 0 {
return false
}
match self.shards[hash % self.shard_count] {
Some(filter) => filter.contains(hash)
None => false
}
}
///|
pub fn ShardedFuseFilter::len(self : ShardedFuseFilter) -> Int {
let mut total = 0
for shard in self.shards {
match shard {
Some(filter) => total = total + filter.len()
None => ()
}
}
total
}
///|
pub fn ShardedFuseFilter::stats(self : ShardedFuseFilter) -> ShardStats {
let mut key_count = 0
let mut populated_shards = 0
let mut smallest_shard = 0
let mut largest_shard = 0
for shard in self.shards {
match shard {
None => ()
Some(filter) => {
let count = filter.len()
key_count = key_count + count
populated_shards = populated_shards + 1
if smallest_shard == 0 || count < smallest_shard {
smallest_shard = count
}
if count > largest_shard {
largest_shard = count
}
}
}
}
{
shard_count: self.shard_count,
key_count,
populated_shards,
smallest_shard,
largest_shard,
}
}
///|
pub fn ShardedFuseFilter::validate(
self : ShardedFuseFilter,
hashes : Array[Int],
) -> Bool {
if self.shard_count <= 0 ||
self.shards.length() != self.shard_count ||
hashes.length() != self.len() {
return false
}
for hash in hashes {
if hash < 0 || !self.contains(hash) {
return false
}
}
true
}