pub fn sync_cache<F: FnOnce() -> bool> (
		&mut self,
		enacted: &[B::Hash],
		retracted: &[B::Hash],
		changes: Vec<(StorageKey, Option<StorageValue>)>,
		commit_hash: Option<B::Hash>,
		commit_number: Option<<B::Header as Header>::Number>,
		is_best: F,
	) {
		let mut cache = self.shared_cache.lock();
		let is_best = is_best();
		trace!("Syncing cache, id = (#{:?}, {:?}), parent={:?}, best={}", commit_number, commit_hash, self.parent_hash, is_best);
		let cache = &mut *cache;

		// Purge changes from re-enacted and retracted blocks.
		// Filter out commiting block if any.
		let mut clear = false;
		for block in enacted.iter().filter(|h| commit_hash.as_ref().map_or(true, |p| *h != p)) {
			clear = clear || {
				if let Some(ref mut m) = cache.modifications.iter_mut().find(|m| &m.hash == block) {
					trace!("Reverting enacted block {:?}", block);
					m.is_canon = true;
					for a in &m.storage {
						trace!("Reverting enacted key {:?}", a);
						cache.storage.remove(a);
					}
					false
				} else {
					true
				}
			};
		}

		for block in retracted {
			clear = clear || {
				if let Some(ref mut m) = cache.modifications.iter_mut().find(|m| &m.hash == block) {
					trace!("Retracting block {:?}", block);
					m.is_canon = false;
					for a in &m.storage {
						trace!("Retracted key {:?}", a);
						cache.storage.remove(a);
					}
					false
				} else {
					true
				}
			};
		}
		if clear {
			// We don't know anything about the block; clear everything
			trace!("Wiping cache");
			cache.storage.clear();
			cache.modifications.clear();
		}

		// Propagate cache only if committing on top of the latest canonical state
		// blocks are ordered by number and only one block with a given number is marked as canonical
		// (contributed to canonical state cache)
		if let Some(_) = self.parent_hash {
			let mut local_cache = self.local_cache.write();
			if is_best {
				trace!("Committing {} local, {} hashes, {} modified entries", local_cache.storage.len(), local_cache.hashes.len(), changes.len());
				for (k, v) in local_cache.storage.drain() {
					cache.storage.insert(k, v);
				}
				for (k, v) in local_cache.hashes.drain() {
					cache.hashes.insert(k, v);
				}
			}
		}

		if let (
			Some(ref number), Some(ref hash), Some(ref parent))
				= (commit_number, commit_hash, self.parent_hash)
		{
			if cache.modifications.len() == STATE_CACHE_BLOCKS {
				cache.modifications.pop_back();
			}
			let mut modifications = HashSet::new();
			for (k, v) in changes.into_iter() {
				modifications.insert(k.clone());
				if is_best {
					cache.hashes.remove(&k);
					cache.storage.insert(k, v);
				}
			}
			// Save modified storage. These are ordered by the block number.
			let block_changes = BlockChanges {
				storage: modifications,
				number: *number,
				hash: hash.clone(),
				is_canon: is_best,
				parent: parent.clone(),
			};
			let insert_at = cache.modifications.iter()
				.enumerate()
				.find(|&(_, m)| m.number < *number)
				.map(|(i, _)| i);
			trace!("Inserting modifications at {:?}", insert_at);
			if let Some(insert_at) = insert_at {
				cache.modifications.insert(insert_at, block_changes);
			} else {
				cache.modifications.push_back(block_changes);
			}
		}
	}
/// Propagate local cache into the shared cache and synchronize
/// the shared cache with the best block state.
/// This function updates the shared cache by removing entries
/// that are invalidated by chain reorganization. `sync_cache`
/// should be called after the block has been committed and the
/// blockchain route has been calculated.
Propagate local cache into the shared cache and synchronize
the shared cache with the best block state.
This function updates the shared cache by removing entries
that are invalidated by chain reorganization. `sync_cache`
should be called after the block has been committed and the
blockchain route has been calculated.
Propagate local cache into the shared cache and synchronize the shared cache with the best block state . This function updates the shared cache by removing entries that are invalidated by chain reorganization . ` sync_cache ` should be called after the block has been committed and the blockchain route has been calculated .
pub fn sync_cache<F: FnOnce() -> bool> (
		&mut self,
		enacted: &[B::Hash],
		retracted: &[B::Hash],
		changes: Vec<(StorageKey, Option<StorageValue>)>,
		commit_hash: Option<B::Hash>,
		commit_number: Option<<B::Header as Header>::Number>,
		is_best: F,
	) {
		let mut cache = self.shared_cache.lock();
		let is_best = is_best();
		trace!("Syncing cache, id = (#{:?}, {:?}), parent={:?}, best={}", commit_number, commit_hash, self.parent_hash, is_best);
		let cache = &mut *cache;
		// Purge changes from re-enacted and retracted blocks.
		// Filter out commiting block if any.
		let mut clear = false;
		for block in enacted.iter().filter(|h| commit_hash.as_ref().map_or(true, |p| *h != p)) {
			clear = clear || {
				if let Some(ref mut m) = cache.modifications.iter_mut().find(|m| &m.hash == block) {
					trace!("Reverting enacted block {:?}", block);
					m.is_canon = true;
					for a in &m.storage {
						trace!("Reverting enacted key {:?}", a);
						cache.storage.remove(a);
					}
					false
				} else {
					true
				}
			};
		}
		for block in retracted {
			clear = clear || {
				if let Some(ref mut m) = cache.modifications.iter_mut().find(|m| &m.hash == block) {
					trace!("Retracting block {:?}", block);
					m.is_canon = false;
					for a in &m.storage {
						trace!("Retracted key {:?}", a);
						cache.storage.remove(a);
					}
					false
				} else {
					true
				}
			};
		}
		if clear {
			// We don't know anything about the block; clear everything
			trace!("Wiping cache");
			cache.storage.clear();
			cache.modifications.clear();
		}
		// Propagate cache only if committing on top of the latest canonical state
		// blocks are ordered by number and only one block with a given number is marked as canonical
		// (contributed to canonical state cache)
		if let Some(_) = self.parent_hash {
			let mut local_cache = self.local_cache.write();
			if is_best {
				trace!("Committing {} local, {} hashes, {} modified entries", local_cache.storage.len(), local_cache.hashes.len(), changes.len());
				for (k, v) in local_cache.storage.drain() {
					cache.storage.insert(k, v);
				}
				for (k, v) in local_cache.hashes.drain() {
					cache.hashes.insert(k, v);
				}
			}
		}
		if let (
			Some(ref number), Some(ref hash), Some(ref parent))
				= (commit_number, commit_hash, self.parent_hash)
		{
			if cache.modifications.len() == STATE_CACHE_BLOCKS {
				cache.modifications.pop_back();
			}
			let mut modifications = HashSet::new();
			for (k, v) in changes.into_iter() {
				modifications.insert(k.clone());
				if is_best {
					cache.hashes.remove(&k);
					cache.storage.insert(k, v);
				}
			}
			// Save modified storage. These are ordered by the block number.
			let block_changes = BlockChanges {
				storage: modifications,
				number: *number,
				hash: hash.clone(),
				is_canon: is_best,
				parent: parent.clone(),
			};
			let insert_at = cache.modifications.iter()
				.enumerate()
				.find(|&(_, m)| m.number < *number)
				.map(|(i, _)| i);
			trace!("Inserting modifications at {:?}", insert_at);
			if let Some(insert_at) = insert_at {
				cache.modifications.insert(insert_at, block_changes);
			} else {
				cache.modifications.push_back(block_changes);
			}
		}
	}
pub fn sync_cache < F : FnOnce ( ) -> bool > ( & mut self , enacted : & [ B :: Hash ] , retracted : & [ B :: Hash ] , changes : Vec < ( StorageKey , Option < StorageValue > ) > , commit_hash : Option < B :: Hash > , commit_number : Option < < B :: Header as Header > :: Number > , is_best : F , ) { let mut cache = self . shared_cache . lock ( ) ; let is_best = is_best ( ) ; trace ! ( " " commit_number commit_hash self parent_hash is_best ) ; let cache = & mut * cache ; // Purge changes from re-enacted and retracted blocks. // Filter out commiting block if any. let mut clear = false ; for block in enacted . iter ( ) . filter ( | h | commit_hash . as_ref ( ) . map_or ( true , | p | * h != p ) ) { clear = clear || { if let Some ( ref mut m ) = cache . modifications . iter_mut ( ) . find ( | m | & m . hash == block ) { trace ! ( " " block ) ; m . is_canon = true ; for a in & m . storage { trace ! ( " " a ) ; cache . storage . remove ( a ) ; } false } else { true } } ; } for block in retracted { clear = clear || { if let Some ( ref mut m ) = cache . modifications . iter_mut ( ) . find ( | m | & m . hash == block ) { trace ! ( " " block ) ; m . is_canon = false ; for a in & m . storage { trace ! ( " " a ) ; cache . storage . remove ( a ) ; } false } else { true } } ; } if clear { // We don't know anything about the block; clear everything trace ! ( " " ) ; cache . storage . clear ( ) ; cache . modifications . clear ( ) ; } // Propagate cache only if committing on top of the latest canonical state // blocks are ordered by number and only one block with a given number is marked as canonical // (contributed to canonical state cache) if let Some ( _ ) = self . parent_hash { let mut local_cache = self . local_cache . write ( ) ; if is_best { trace ! ( " " local_cache storage len ( ) local_cache hashes len ( ) changes len ( ) ) ; for ( k , v ) in local_cache . storage . drain ( ) { cache . storage . insert ( k , v ) ; } for ( k , v ) in local_cache . hashes . drain ( ) { cache . hashes . insert ( k , v ) ; } } } if let ( Some ( ref number ) , Some ( ref hash ) , Some ( ref parent ) ) = ( commit_number , commit_hash , self . parent_hash ) { if cache . modifications . len ( ) == STATE_CACHE_BLOCKS { cache . modifications . pop_back ( ) ; } let mut modifications = HashSet :: new ( ) ; for ( k , v ) in changes . into_iter ( ) { modifications . insert ( k . clone ( ) ) ; if is_best { cache . hashes . remove ( & k ) ; cache . storage . insert ( k , v ) ; } } // Save modified storage. These are ordered by the block number. let block_changes = BlockChanges { storage : modifications , number : * number , hash : hash . clone ( ) , is_canon : is_best , parent : parent . clone ( ) , } ; let insert_at = cache . modifications . iter ( ) . enumerate ( ) . find ( | & ( _ , m ) | m . number < * number ) . map ( | ( i , _ ) | i ) ; trace ! ( " " insert_at ) ; if let Some ( insert_at ) = insert_at { cache . modifications . insert ( insert_at , block_changes ) ; } else { cache . modifications . push_back ( block_changes ) ; } } }
Propagate local cache into the shared cache and synchronize
the shared cache with the best block state.
Propagate local cache into the shared cache and synchronize the shared cache with the best block state .
&mut self
enacted
&[B::Hash]
retracted
&[B::Hash]
changes
Vec<(StorageKey, Option<StorageValue>)>
commit_hash
Option<B::Hash>
commit_number
Option<<B::Header as Header>::Number>
is_best
F
&mut self
enacted
&[B::Hash]
retracted
&[B::Hash]
changes
Vec<(StorageKey, Option<StorageValue>)>
commit_hash
Option<B::Hash>
commit_number
Option<<B::Header as Header>::Number>
is_best
F