[−][src]Struct exonum_merkledb::migration::MigrationHelper
Migration helper.
Examples
See the module docs for a basic example of usage.
Aborting migration
MigrationHelper
offers AbortHandle
to abort migration logic. Once aborted, MigrationHelper
does not allow to merge changes to the database; the relevant methods will return
MigrationError::Aborted
. This is important, e.g., to prevent unnecessary writes
to the database.
let db = TemporaryDB::new(); // Since `MigrationHelper` cannot be sent between threads, we instantiate it // in a newly spawned thread and move the helper handle to the main thread. let (tx, rx) = mpsc::channel(); let helper_thread = thread::spawn(move || { let (mut helper, handle) = MigrationHelper::with_handle(db, "test"); tx.send(handle).unwrap(); // Emulate some work... thread::sleep(Duration::from_millis(50)); // Attempt to merge changes to DB. helper.merge() }); let handle = rx.recv().unwrap(); // Migration is automatically aborted when the handle is dropped. drop(handle); let res: Result<(), MigrationError> = helper_thread.join().unwrap(); assert_matches!(res, Err(MigrationError::Aborted));
Using persistent iterators
MigrationHelper
offers the iter_loop
method, which allows to further
simplify working with persistent iterators.
Say we want to migrate MapIndex
data to a ProofMapIndex
while merging changes to the DB
from time to time. To do this, we use the following script:
/// Number of accounts processed per DB merge. const CHUNK_SIZE: usize = 100; let db = TemporaryDB::new(); let mut helper = MigrationHelper::new(db, "test"); helper.iter_loop(|helper, iters| { // The data before migration is stored in this map let old_map = helper.old_data().get_map::<_, str, u64>("wallets"); // ...and the new data is in this merkelized map. let mut new_map = helper.new_data().get_proof_map::<_, str, u64>("wallets"); // Create an iterator over the old data. let iter = iters.create("wallets", &old_map); // Take a fixed amount of records from the iterator and migrate them. // Since `iter` is persistent, it will not return the same record twice, // even if this script is restarted. for (name, balance) in iter.take(CHUNK_SIZE) { new_map.put(&name, balance); } })?; // Here, the iterator has run out of items. The script can now perform // other actions if necessary.
Methods
impl MigrationHelper
[src]
pub fn new(db: impl Into<Arc<dyn Database>>, namespace: &str) -> Self
[src]
Creates a new helper.
pub fn with_handle(
db: impl Into<Arc<dyn Database>>,
namespace: &str
) -> (Self, AbortHandle)
[src]
db: impl Into<Arc<dyn Database>>,
namespace: &str
) -> (Self, AbortHandle)
Creates a new helper together with the abort handle. Unlike the MigrationHelper
,
the handle may be sent between threads. The handle allows to determine whether the migration
helper was completed, and allows to abort the migration by preventing further writes
to the database.
pub fn new_data(&self) -> Migration<&Fork>
[src]
Returns full access to the new version of migrated data.
pub fn scratchpad(&self) -> Scratchpad<&Fork>
[src]
Returns the scratchpad for temporary data to use during migration.
pub fn old_data(&self) -> Prefixed<ReadonlyFork>
[src]
Returns readonly access to the old version of migrated data.
pub fn merge(&mut self) -> Result<(), MigrationError>
[src]
Merges the changes to the migrated data and the scratchpad to the database. Returns an error if the merge has failed.
merge
does not flush the migration; the migrated data remains in a separate namespace.
Use flush_migration
to flush the migrated data.
pub fn iter_loop(
&mut self,
step: impl FnMut(&Self, &mut PersistentIters<Scratchpad<&Fork>>)
) -> Result<(), MigrationError>
[src]
&mut self,
step: impl FnMut(&Self, &mut PersistentIters<Scratchpad<&Fork>>)
) -> Result<(), MigrationError>
Executes the provided closure in a loop until all persistent iterators instantiated within the closure have ended. After each iteration, the changes in migrated data are merged to the database; an error is returned if this merge fails.
If no iterators are instantiated within the closure, a single iteration will be performed.
pub fn finish(self) -> Result<Hash, MigrationError>
[src]
Merges the changes to the migrated data and the migration scratchpad to the database. Returns hash representing migrated data state, or an error if the merge has failed.
finish
does not flush the migration; the migrated data remains in a separate namespace.
Use flush_migration
to flush the migrated data.
Trait Implementations
Auto Trait Implementations
impl !RefUnwindSafe for MigrationHelper
impl !Send for MigrationHelper
impl !Sync for MigrationHelper
impl Unpin for MigrationHelper
impl !UnwindSafe for MigrationHelper
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>
[src]
impl<V, T> VZip<V> for T where
V: MultiLane<T>,
V: MultiLane<T>,