[][src]Struct exonum_merkledb::migration::PersistentIter

pub struct PersistentIter<'a, T: RawAccess, I: IndexIterator> { /* fields omitted */ }

Persistent iterator that stores its position in the database.

Persistent iterators iterate over an index and automatically persist iteration results in the DB. This allows to build fault-tolerant migration scripts that work correctly after being restarted while merging the intermediate changes to the database.

Like indexes, persistent iterators are identified by an address. Likewise, they are subject to the borrowing rules (e.g., attempting to create two instances of the same iterator will result in a runtime error). When migrating data, it makes sense to store iterators in the associated Scratchpad. In this way, iterators will be automatically removed when the migration is over.

Examples

MigrationHelper offers convenient iterator API via iter_loop method, which covers basic use cases. When iter_loop is not enough, a persistent iterator can be instantiated independently:

let db = TemporaryDB::new();
// Create data for migration.
let fork = db.fork();
fork.get_proof_list("migration.list").extend((0..123).map(|i| i.to_string()));
db.merge(fork.into_patch()).unwrap();

let helper = MigrationHelper::new(db, "migration");
// The old data is here.
let list = helper.old_data().get_proof_list::<_, String>("list");
// In the context of migration, persistent iterators should use
// the scratchpad data access.
let iter = PersistentIter::new(&helper.scratchpad(), "list_iter", &list);
// Now, we can use `iter` as any other iterator. Persistence is most useful
// together with the `take` adapter; it allows to break migrated data
// into manageable chunks.
for (_, item) in iter.take(100) {
    // Migrate `item`. The first component of a tuple is the index of the item
    // in the list, which we ignore.
}

// If we recreate the iterator, it will resume iteration from the last
// known position (the element with 0-based index 100, in our case).
let mut iter = PersistentIter::new(&helper.scratchpad(), "list_iter", &list);
let (i, item) = iter.next().unwrap();
assert_eq!(i, 100);
assert_eq!(item, "100");
assert_eq!(iter.count(), 22); // number of remaining items

Methods

impl<'a, T, I> PersistentIter<'a, T, I> where
    T: RawAccessMut,
    I: IndexIterator
[src]

pub fn new<A>(access: &A, name: &str, index: &'a I) -> Self where
    A: Access<Base = T>, 
[src]

Creates a new persistent iterator.

pub fn skip_values(self) -> PersistentKeys<'a, T, I>[src]

Skips values in the iterator output without parsing them.

Trait Implementations

impl<'_, T, I> Debug for PersistentIter<'_, T, I> where
    T: RawAccess,
    I: IndexIterator,
    I::Key: Debug
[src]

impl<'_, T, I> Iterator for PersistentIter<'_, T, I> where
    T: RawAccessMut,
    I: IndexIterator
[src]

type Item = (<I::Key as ToOwned>::Owned, I::Value)

The type of the elements being iterated over.

Auto Trait Implementations

impl<'a, T, I> !RefUnwindSafe for PersistentIter<'a, T, I>

impl<'a, T, I> !Send for PersistentIter<'a, T, I>

impl<'a, T, I> !Sync for PersistentIter<'a, T, I>

impl<'a, T, I> Unpin for PersistentIter<'a, T, I> where
    T: Unpin,
    <T as RawAccess>::Changes: Unpin,
    <I as IndexIterator>::Key: BinaryKey + ToOwned + Unpin,
    <<I as IndexIterator>::Key as ToOwned>::Owned: Unpin,
    <I as IndexIterator>::Value: BinaryValue + Unpin

impl<'a, T, I> !UnwindSafe for PersistentIter<'a, T, I>

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

type IntoIter = I

Which kind of iterator are we turning this into?

impl<I> IteratorRandom for I where
    I: Iterator
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

impl<V, T> VZip<V> for T where
    V: MultiLane<T>,