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:
Marek Kotewicz
2018-01-14 22:43:28 +01:00
committed by GitHub
parent e7f36665bb
commit 668d910c44
65 changed files with 2023 additions and 519 deletions

View 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))
}
}

View 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)
}
}

View File

@@ -0,0 +1,6 @@
use group::{GroupPosition, BloomGroup};
/// Readonly `BloomGroup` database.
pub trait BloomGroupDatabase {
fn blooms_at(&self, position: &GroupPosition) -> Option<BloomGroup>;
}

View 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
}
}
}

View 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;

View 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,
}
}
}

View File

@@ -0,0 +1,5 @@
mod position;
mod manager;
pub use self::position::{Position, GroupPosition};
pub use self::manager::Manager;

View 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,
}