bloom filter uses vector instead of hashmap, added few comments
This commit is contained in:
parent
1a30d91853
commit
d1223b3b15
@ -35,24 +35,26 @@ pub struct ChainFilter<'a, D>
|
|||||||
{
|
{
|
||||||
data_source: &'a D,
|
data_source: &'a D,
|
||||||
index_size: usize,
|
index_size: usize,
|
||||||
levels: u8,
|
level_sizes: Vec<usize>,
|
||||||
level_sizes: HashMap<u8, usize>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, D> ChainFilter<'a, D> where D: FilterDataSource
|
impl<'a, D> ChainFilter<'a, D> where D: FilterDataSource
|
||||||
{
|
{
|
||||||
/// creates new filter instance
|
/// creates new filter instance
|
||||||
pub fn new(data_source: &'a D, index_size: usize, levels: u8) -> Self {
|
pub fn new(data_source: &'a D, index_size: usize, levels: u8) -> Self {
|
||||||
|
if levels == 0 {
|
||||||
|
panic!("ChainFilter requires and least 1 level");
|
||||||
|
}
|
||||||
|
|
||||||
let mut filter = ChainFilter {
|
let mut filter = ChainFilter {
|
||||||
data_source: data_source,
|
data_source: data_source,
|
||||||
index_size: index_size,
|
index_size: index_size,
|
||||||
levels: levels,
|
level_sizes: vec![]
|
||||||
level_sizes: HashMap::new(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// cache level sizes, so we do not have to calculate them all the time
|
// cache level sizes, so we do not have to calculate them all the time
|
||||||
for i in 0..levels {
|
for i in 0..levels {
|
||||||
filter.level_sizes.insert(i, pow(index_size, i as usize));
|
filter.level_sizes.push(pow(index_size, i as usize));
|
||||||
}
|
}
|
||||||
|
|
||||||
filter
|
filter
|
||||||
@ -60,7 +62,7 @@ impl<'a, D> ChainFilter<'a, D> where D: FilterDataSource
|
|||||||
|
|
||||||
/// unsafely get level size
|
/// unsafely get level size
|
||||||
fn level_size(&self, level: u8) -> usize {
|
fn level_size(&self, level: u8) -> usize {
|
||||||
*self.level_sizes.get(&level).unwrap()
|
self.level_sizes[level as usize]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// converts block number and level to `BloomIndex`
|
/// converts block number and level to `BloomIndex`
|
||||||
@ -95,9 +97,14 @@ impl<'a, D> ChainFilter<'a, D> where D: FilterDataSource
|
|||||||
indexes
|
indexes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// return number of levels
|
||||||
|
fn levels(&self) -> u8 {
|
||||||
|
self.level_sizes.len() as u8
|
||||||
|
}
|
||||||
|
|
||||||
/// returns max filter level
|
/// returns max filter level
|
||||||
fn max_level(&self) -> u8 {
|
fn max_level(&self) -> u8 {
|
||||||
self.levels - 1
|
self.level_sizes.len() as u8 - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
/// internal function which actually does bloom search
|
/// internal function which actually does bloom search
|
||||||
@ -146,7 +153,7 @@ impl<'a, D> Filter for ChainFilter<'a, D> where D: FilterDataSource
|
|||||||
fn add_bloom(&self, bloom: &H2048, block_number: usize) -> HashMap<BloomIndex, H2048> {
|
fn add_bloom(&self, bloom: &H2048, block_number: usize) -> HashMap<BloomIndex, H2048> {
|
||||||
let mut result: HashMap<BloomIndex, H2048> = HashMap::new();
|
let mut result: HashMap<BloomIndex, H2048> = HashMap::new();
|
||||||
|
|
||||||
for level in 0..self.levels {
|
for level in 0..self.levels() {
|
||||||
let bloom_index = self.bloom_index(block_number, level);
|
let bloom_index = self.bloom_index(block_number, level);
|
||||||
let new_bloom = match self.data_source.bloom_at_index(&bloom_index) {
|
let new_bloom = match self.data_source.bloom_at_index(&bloom_index) {
|
||||||
Some(old_bloom) => old_bloom | bloom,
|
Some(old_bloom) => old_bloom | bloom,
|
||||||
@ -165,7 +172,7 @@ impl<'a, D> Filter for ChainFilter<'a, D> where D: FilterDataSource
|
|||||||
fn add_blooms(&self, blooms: &[H2048], block_number: usize) -> HashMap<BloomIndex, H2048> {
|
fn add_blooms(&self, blooms: &[H2048], block_number: usize) -> HashMap<BloomIndex, H2048> {
|
||||||
let mut result: HashMap<BloomIndex, H2048> = HashMap::new();
|
let mut result: HashMap<BloomIndex, H2048> = HashMap::new();
|
||||||
|
|
||||||
for level in 0..self.levels {
|
for level in 0..self.levels() {
|
||||||
for i in 0..blooms.len() {
|
for i in 0..blooms.len() {
|
||||||
let bloom_index = self.bloom_index(block_number + i, level);
|
let bloom_index = self.bloom_index(block_number + i, level);
|
||||||
let is_new_bloom = match result.get_mut(&bloom_index) {
|
let is_new_bloom = match result.get_mut(&bloom_index) {
|
||||||
@ -199,13 +206,18 @@ impl<'a, D> Filter for ChainFilter<'a, D> where D: FilterDataSource
|
|||||||
let mut reset_index = self.bloom_index(block_number, 0);
|
let mut reset_index = self.bloom_index(block_number, 0);
|
||||||
result.insert(reset_index.clone(), bloom.clone());
|
result.insert(reset_index.clone(), bloom.clone());
|
||||||
|
|
||||||
for level in 1..self.levels {
|
for level in 1..self.levels() {
|
||||||
let index = self.bloom_index(block_number, level);
|
let index = self.bloom_index(block_number, level);
|
||||||
|
// get all bloom indexes that were used to construct this bloom
|
||||||
let lower_indexes = self.lower_level_bloom_indexes(&index);
|
let lower_indexes = self.lower_level_bloom_indexes(&index);
|
||||||
let new_bloom = lower_indexes.into_iter()
|
let new_bloom = lower_indexes.into_iter()
|
||||||
|
// skip reseted one
|
||||||
.filter(|li| li != &reset_index)
|
.filter(|li| li != &reset_index)
|
||||||
|
// get blooms for these indexes
|
||||||
.map(|li| self.data_source.bloom_at_index(&li))
|
.map(|li| self.data_source.bloom_at_index(&li))
|
||||||
|
// filter existing ones
|
||||||
.filter_map(|b| b)
|
.filter_map(|b| b)
|
||||||
|
// BitOr all of them
|
||||||
.fold(H2048::new(), |acc, bloom| &acc | bloom);
|
.fold(H2048::new(), |acc, bloom| &acc | bloom);
|
||||||
|
|
||||||
reset_index = index.clone();
|
reset_index = index.clone();
|
||||||
|
Loading…
Reference in New Issue
Block a user