bloom refactor (#7475)
* ethereum-types refactor in progress * ethereum-types refactor in progress * ethereum-types refactor in progress * ethereum-types refactor in progress * ethereum-types refactor finished * cleanup bloom mess * simplify usage of Bloom in few places * removed obsolete util/src/lib.rs * removed commented out code * ethereum-types 0.1.4 * updated ethereum-types and tiny-keccak
This commit is contained in:
31
util/bloomchain/src/group/bridge.rs
Normal file
31
util/bloomchain/src/group/bridge.rs
Normal file
@@ -0,0 +1,31 @@
|
||||
use bloom::Bloom;
|
||||
use config::Config;
|
||||
use database::BloomDatabase;
|
||||
use position::Position;
|
||||
use group::position::Manager as PositionManager;
|
||||
use super::BloomGroupDatabase;
|
||||
|
||||
/// Bridge between `BloomDatabase` and `BloomGroupDatabase`.
|
||||
pub struct GroupDatabaseBridge<'a> {
|
||||
positioner: PositionManager,
|
||||
db: &'a BloomGroupDatabase,
|
||||
}
|
||||
|
||||
impl<'a> GroupDatabaseBridge<'a> {
|
||||
pub fn new(config: Config, db: &'a BloomGroupDatabase) -> Self {
|
||||
let positioner = PositionManager::new(config.elements_per_index);
|
||||
|
||||
GroupDatabaseBridge {
|
||||
positioner: positioner,
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> BloomDatabase for GroupDatabaseBridge<'a> {
|
||||
fn bloom_at(&self, position: &Position) -> Option<Bloom> {
|
||||
let position = self.positioner.position(position);
|
||||
self.db.blooms_at(&position.group)
|
||||
.and_then(|group| group.blooms.into_iter().nth(position.number))
|
||||
}
|
||||
}
|
||||
70
util/bloomchain/src/group/chain.rs
Normal file
70
util/bloomchain/src/group/chain.rs
Normal file
@@ -0,0 +1,70 @@
|
||||
use std::collections::HashMap;
|
||||
use std::ops::Range;
|
||||
use bloom::Bloom;
|
||||
use chain::BloomChain;
|
||||
use config::Config;
|
||||
use number::Number;
|
||||
use filter::Filter;
|
||||
use position::Position as BloomPosition;
|
||||
use super::{GroupDatabaseBridge, BloomGroupDatabase, BloomGroup, GroupPosition};
|
||||
use super::position::Manager as PositionManager;
|
||||
|
||||
/// Performs all bloom database operations using `BloomGroup`s.
|
||||
pub struct BloomGroupChain<'a> {
|
||||
config: Config,
|
||||
db: &'a BloomGroupDatabase,
|
||||
bridge: GroupDatabaseBridge<'a>,
|
||||
}
|
||||
|
||||
impl<'a> BloomGroupChain<'a> {
|
||||
pub fn new(config: Config, db: &'a BloomGroupDatabase) -> Self {
|
||||
let bridge = GroupDatabaseBridge::new(config, db);
|
||||
|
||||
BloomGroupChain {
|
||||
config: config,
|
||||
db: db,
|
||||
bridge: bridge,
|
||||
}
|
||||
}
|
||||
|
||||
fn group_blooms(&self, blooms: HashMap<BloomPosition, Bloom>) -> HashMap<GroupPosition, BloomGroup> {
|
||||
let positioner = PositionManager::new(self.config.elements_per_index);
|
||||
blooms.into_iter()
|
||||
.fold(HashMap::new(), | mut acc, (position, bloom) | {
|
||||
{
|
||||
let position = positioner.position(&position);
|
||||
let group = acc
|
||||
.entry(position.group.clone())
|
||||
.or_insert_with(|| self.db
|
||||
.blooms_at(&position.group)
|
||||
.unwrap_or_else(|| BloomGroup::new(self.config.elements_per_index))
|
||||
);
|
||||
assert_eq!(self.config.elements_per_index, group.blooms.len());
|
||||
group.blooms[position.number] = bloom;
|
||||
}
|
||||
acc
|
||||
})
|
||||
}
|
||||
|
||||
pub fn insert(&self, number: Number, bloom: Bloom) -> HashMap<GroupPosition, BloomGroup> {
|
||||
let bloom_chain = BloomChain::new(self.config, &self.bridge);
|
||||
let modified_blooms = bloom_chain.insert(number, bloom);
|
||||
self.group_blooms(modified_blooms)
|
||||
}
|
||||
|
||||
pub fn replace(&self, range: &Range<Number>, blooms: Vec<Bloom>) -> HashMap<GroupPosition, BloomGroup> {
|
||||
let bloom_chain = BloomChain::new(self.config, &self.bridge);
|
||||
let modified_blooms = bloom_chain.replace(range, blooms);
|
||||
self.group_blooms(modified_blooms)
|
||||
}
|
||||
|
||||
pub fn with_bloom(&self, range: &Range<Number>, bloom: &Bloom) -> Vec<Number> {
|
||||
let bloom_chain = BloomChain::new(self.config, &self.bridge);
|
||||
bloom_chain.with_bloom(range, bloom)
|
||||
}
|
||||
|
||||
pub fn filter(&self, filter: &Filter) -> Vec<Number> {
|
||||
let bloom_chain = BloomChain::new(self.config, &self.bridge);
|
||||
bloom_chain.filter(filter)
|
||||
}
|
||||
}
|
||||
6
util/bloomchain/src/group/database.rs
Normal file
6
util/bloomchain/src/group/database.rs
Normal file
@@ -0,0 +1,6 @@
|
||||
use group::{GroupPosition, BloomGroup};
|
||||
|
||||
/// Readonly `BloomGroup` database.
|
||||
pub trait BloomGroupDatabase {
|
||||
fn blooms_at(&self, position: &GroupPosition) -> Option<BloomGroup>;
|
||||
}
|
||||
17
util/bloomchain/src/group/group.rs
Normal file
17
util/bloomchain/src/group/group.rs
Normal file
@@ -0,0 +1,17 @@
|
||||
use bloom::Bloom;
|
||||
|
||||
/// Group of blooms that are in the same index.
|
||||
#[derive(Clone)]
|
||||
pub struct BloomGroup {
|
||||
pub blooms: Vec<Bloom>,
|
||||
}
|
||||
|
||||
impl BloomGroup {
|
||||
pub fn new(size: usize) -> Self {
|
||||
let blooms = (0..size).into_iter().map(|_| Bloom::default()).collect();
|
||||
|
||||
BloomGroup {
|
||||
blooms: blooms
|
||||
}
|
||||
}
|
||||
}
|
||||
16
util/bloomchain/src/group/mod.rs
Normal file
16
util/bloomchain/src/group/mod.rs
Normal file
@@ -0,0 +1,16 @@
|
||||
//! Bloom grouping.
|
||||
//!
|
||||
//! Optimization gathering together blooms that are in the same index and are likely to be retrived together.
|
||||
|
||||
mod bridge;
|
||||
mod chain;
|
||||
mod database;
|
||||
mod group;
|
||||
mod position;
|
||||
|
||||
pub use self::bridge::GroupDatabaseBridge;
|
||||
pub use self::chain::BloomGroupChain;
|
||||
|
||||
pub use self::database::BloomGroupDatabase;
|
||||
pub use self::group::BloomGroup;
|
||||
pub use self::position::GroupPosition;
|
||||
28
util/bloomchain/src/group/position/manager.rs
Normal file
28
util/bloomchain/src/group/position/manager.rs
Normal file
@@ -0,0 +1,28 @@
|
||||
use super::{Position, GroupPosition};
|
||||
use position::Position as BloomPosition;
|
||||
|
||||
pub struct Manager {
|
||||
index_size: usize
|
||||
}
|
||||
|
||||
impl Manager {
|
||||
pub fn new(index_size: usize) -> Self {
|
||||
Manager {
|
||||
index_size: index_size
|
||||
}
|
||||
}
|
||||
|
||||
pub fn group_position(&self, pos: &BloomPosition) -> GroupPosition {
|
||||
GroupPosition {
|
||||
level: pos.level,
|
||||
index: pos.index / self.index_size,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn position(&self, pos: &BloomPosition) -> Position {
|
||||
Position {
|
||||
group: self.group_position(pos),
|
||||
number: pos.index % self.index_size,
|
||||
}
|
||||
}
|
||||
}
|
||||
5
util/bloomchain/src/group/position/mod.rs
Normal file
5
util/bloomchain/src/group/position/mod.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
mod position;
|
||||
mod manager;
|
||||
|
||||
pub use self::position::{Position, GroupPosition};
|
||||
pub use self::manager::Manager;
|
||||
17
util/bloomchain/src/group/position/position.rs
Normal file
17
util/bloomchain/src/group/position/position.rs
Normal file
@@ -0,0 +1,17 @@
|
||||
/// Uniquely identifies bloom group position.
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
|
||||
pub struct GroupPosition {
|
||||
/// Bloom level.
|
||||
pub level: usize,
|
||||
/// Index of the group.
|
||||
pub index: usize,
|
||||
}
|
||||
|
||||
/// Uniquely identifies bloom position including the position in the group.
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
|
||||
pub struct Position {
|
||||
/// Group position.
|
||||
pub group: GroupPosition,
|
||||
/// Number in group.
|
||||
pub number: usize,
|
||||
}
|
||||
Reference in New Issue
Block a user