From c41f41fee8d7d45e059b8bdf90b7f2e1b4cbd69b Mon Sep 17 00:00:00 2001 From: Milosz Muszynski Date: Wed, 13 Nov 2024 20:04:49 +0100 Subject: [PATCH] piecrust: main index in commit store --- piecrust/src/store.rs | 35 ++++++++++++++++++++++----- piecrust/src/store/commit.rs | 47 ++++++++++++++++++++---------------- piecrust/src/store/tree.rs | 19 +++++++++------ 3 files changed, 66 insertions(+), 35 deletions(-) diff --git a/piecrust/src/store.rs b/piecrust/src/store.rs index a8ee9019..784cff75 100644 --- a/piecrust/src/store.rs +++ b/piecrust/src/store.rs @@ -72,12 +72,14 @@ impl Debug for ContractStore { #[derive(Debug)] pub struct CommitStore { commits: BTreeMap, + main_index: NewContractIndex, } impl CommitStore { pub fn new() -> Self { Self { commits: BTreeMap::new(), + main_index: NewContractIndex::new(), } } @@ -89,6 +91,23 @@ impl CommitStore { self.commits.get(hash) } + pub fn get_element_and_base( + &self, + hash: &Hash, + contract_id: &ContractId, + ) -> (Option<*const ContractIndexElement>, Option) { + match self.commits.get(hash) { + Some(commit) => { + let e = commit.index.get(contract_id); + (e.map(|a| a as *const ContractIndexElement), commit.base) + } + None => { + let e = self.main_index.get(contract_id); + (e.map(|a| a as *const ContractIndexElement), None) + } + } + } + pub fn contains_key(&self, hash: &Hash) -> bool { self.commits.contains_key(hash) } @@ -98,7 +117,9 @@ impl CommitStore { } pub fn remove_commit(&mut self, hash: &Hash) { - self.commits.remove(hash); + if let Some(commit) = self.commits.remove(hash) { + commit.index.move_into(&mut self.main_index); + } } } @@ -537,7 +558,7 @@ impl Commit { ) -> Self { let mut index = NewContractIndex::new(); for contract_id in contract_ids { - if let Some(a) = self.index.get(contract_id, None) { + if let Some(a) = self.index.get(contract_id) { index.insert_contract_index(contract_id, a.clone()); } } @@ -585,7 +606,7 @@ impl Commit { } pub fn insert(&mut self, contract_id: ContractId, memory: &Memory) { - if self.index.get(&contract_id, None).is_none() { + if self.index.get(&contract_id).is_none() { self.index.insert_contract_index( &contract_id, ContractIndexElement::new(memory.is_64()), @@ -598,7 +619,11 @@ impl Commit { for (dirty_page, _, page_index) in memory.dirty_pages() { let hash = Hash::new(dirty_page); - element.insert_page_index_hash(*page_index as u64, hash); + element.insert_page_index_hash( + *page_index, + *page_index as u64, + hash, + ); } let root = *element.tree().root(); @@ -855,8 +880,6 @@ fn write_commit>( let root = *commit.root(); let root_hex = hex::encode(root); - commit.maybe_hash = Some(root); - commit.base = base_info.maybe_base; // Don't write the commit if it already exists on disk. This may happen if // the same transactions on the same base commit for example. diff --git a/piecrust/src/store/commit.rs b/piecrust/src/store/commit.rs index 873b622d..702a7f8a 100644 --- a/piecrust/src/store/commit.rs +++ b/piecrust/src/store/commit.rs @@ -58,7 +58,7 @@ impl CommitHulk { Some(p) => { let mut partial_index_clone = NewContractIndex::new(); for contract_id in commit_contracts.keys() { - if let Some(a) = p.get(contract_id, None) { + if let Some(a) = p.get(contract_id) { partial_index_clone .insert_contract_index(contract_id, a.clone()); } @@ -144,7 +144,11 @@ impl CommitHulk { for (dirty_page, _, page_index) in memory.dirty_pages() { let hash = Hash::new(dirty_page); - element.insert_page_index_hash(*page_index as u64, hash); + element.insert_page_index_hash( + *page_index, + *page_index as u64, + hash, + ); } let root = *element.tree().root(); @@ -193,17 +197,16 @@ impl CommitHulk { ) -> Option<&ContractIndexElement> { let index = self.index.map(|p| unsafe { p.as_ref().unwrap() }); match index { - Some(p) => self.index2.get(contract_id, self.maybe_hash).or_else( - move || { - Self::deep_index_get( - p, - *contract_id, - self.commit_store.clone(), - self.base, - ) - }, - ), - None => self.index2.get(contract_id, self.maybe_hash), + Some(p) => self.index2.get(contract_id).or_else(move || { + Self::deep_index_get( + p, + *contract_id, + self.commit_store.clone(), + self.base, + ) + .map(|a| unsafe { &*a }) + }), + None => self.index2.get(contract_id), } } @@ -237,11 +240,12 @@ impl CommitHulk { let commit_store = commit_store.clone()?; let commit_store = commit_store.lock().unwrap(); loop { - let commit = commit_store.get_commit(&base)?; - if commit.index.contains_key(contract_id) { + let (maybe_element, commit_base) = + commit_store.get_element_and_base(&base, contract_id); + if maybe_element.is_some() { return Some(()); } - base = commit.base?; + base = commit_base?; } } @@ -265,19 +269,20 @@ impl CommitHulk { contract_id: ContractId, commit_store: Option>>, base: Option, - ) -> Option<&ContractIndexElement> { - if let Some(e) = index.get(&contract_id, None) { + ) -> Option<*const ContractIndexElement> { + if let Some(e) = index.get(&contract_id) { return Some(e); } let mut base = base?; let commit_store = commit_store.clone()?; let commit_store = commit_store.lock().unwrap(); loop { - let commit = commit_store.get_commit(&base)?; - if let Some(e) = index.get(&contract_id, None) { + let (maybe_element, commit_base) = + commit_store.get_element_and_base(&base, &contract_id); + if let Some(e) = maybe_element { return Some(e); } - base = commit.base?; + base = commit_base?; } } } diff --git a/piecrust/src/store/tree.rs b/piecrust/src/store/tree.rs index a1202af1..c3370393 100644 --- a/piecrust/src/store/tree.rs +++ b/piecrust/src/store/tree.rs @@ -214,11 +214,12 @@ impl ContractIndexElement { pub fn insert_page_index_hash( &mut self, - page_index: u64, + page_index: usize, + page_index_u64: u64, page_hash: impl Into, ) { - self.page_indices.insert(page_index as usize); - self.tree.insert(page_index, page_hash); + self.page_indices.insert(page_index); + self.tree.insert(page_index_u64, page_hash); } } @@ -250,11 +251,7 @@ impl NewContractIndex { self.inner_contracts.insert(*contract_id, element); } - pub fn get( - &self, - contract: &ContractId, - _maybe_commit_id: Option, - ) -> Option<&ContractIndexElement> { + pub fn get(&self, contract: &ContractId) -> Option<&ContractIndexElement> { self.inner_contracts.get(contract) } @@ -275,6 +272,12 @@ impl NewContractIndex { ) -> impl Iterator { self.inner_contracts.iter() } + + pub fn move_into(self, target: &mut Self) { + for (contract_id, element) in self.inner_contracts.into_iter() { + target.insert_contract_index(&contract_id, element); + } + } } type Wasm32PageOpening = dusk_merkle::Opening;