pub fn read<K, V, T, S, E>(
    correlation_id: CorrelationId,
    txn: &T,
    store: &S,
    root: &Blake2bHash,
    key: &K,
) -> Result<ReadResult<V>, E>
where
    K: ToBytes + FromBytes + Eq + std::fmt::Debug,
    V: ToBytes + FromBytes,
    T: Readable<Handle = S::Handle>,
    S: TrieStore<K, V>,
    S::Error: From<T::Error>,
    E: From<S::Error> + From<contract_ffi::bytesrepr::Error>,
{
    let path: Vec<u8> = key.to_bytes()?;

    let mut depth: usize = 0;
    let mut current: Trie<K, V> = match store.get(txn, root)? {
        Some(root) => root,
        None => return Ok(ReadResult::RootNotFound),
    };

    let start = Instant::now();
    let mut get_counter: i32 = 0;

    loop {
        match current {
            Trie::Leaf {
                key: leaf_key,
                value: leaf_value,
            } => {
                let result = if *key == leaf_key {
                    ReadResult::Found(leaf_value)
                } else {
                    // Keys may not match in the case of a compressed path from
                    // a Node directly to a Leaf
                    ReadResult::NotFound
                };
                log_metric(
                    correlation_id,
                    TRIE_STORE_READ_GETS,
                    GET,
                    GAUGE,
                    f64::from(get_counter),
                );
                log_duration(
                    correlation_id,
                    TRIE_STORE_READ_DURATION,
                    READ,
                    start.elapsed(),
                );
                return Ok(result);
            }
            Trie::Node { pointer_block } => {
                let index: usize = {
                    assert!(depth < path.len(), "depth must be < {}", path.len());
                    path[depth].into()
                };
                let maybe_pointer: Option<Pointer> = {
                    assert!(index < trie::RADIX, "key length must be < {}", trie::RADIX);
                    pointer_block[index]
                };
                match maybe_pointer {
                    Some(pointer) => match store.get(txn, pointer.hash())? {
                        Some(next) => {
                            get_counter += 1;
                            depth += 1;
                            current = next;
                        }
                        None => {
                            get_counter += 1;
                            log_metric(
                                correlation_id,
                                TRIE_STORE_READ_GETS,
                                GET,
                                GAUGE,
                                f64::from(get_counter),
                            );
                            log_duration(
                                correlation_id,
                                TRIE_STORE_READ_DURATION,
                                READ,
                                start.elapsed(),
                            );
                            panic!(
                                "No trie value at key: {:?} (reading from key: {:?})",
                                pointer.hash(),
                                key
                            );
                        }
                    },
                    None => {
                        log_metric(
                            correlation_id,
                            TRIE_STORE_READ_GETS,
                            GET,
                            GAUGE,
                            f64::from(get_counter),
                        );
                        log_duration(
                            correlation_id,
                            TRIE_STORE_READ_DURATION,
                            READ,
                            start.elapsed(),
                        );
                        return Ok(ReadResult::NotFound);
                    }
                }
            }
            Trie::Extension { affix, pointer } => {
                let sub_path = &path[depth..depth + affix.len()];
                if sub_path == affix.as_slice() {
                    get_counter += 1;
                    match store.get(txn, pointer.hash())? {
                        Some(next) => {
                            get_counter += 1;
                            depth += affix.len();
                            current = next;
                        }
                        None => {
                            get_counter += 1;
                            log_metric(
                                correlation_id,
                                TRIE_STORE_READ_GETS,
                                GET,
                                GAUGE,
                                f64::from(get_counter),
                            );
                            log_duration(
                                correlation_id,
                                TRIE_STORE_READ_DURATION,
                                READ,
                                start.elapsed(),
                            );
                            panic!(
                                "No trie value at key: {:?} (reading from key: {:?})",
                                pointer.hash(),
                                key
                            );
                        }
                    }
                } else {
                    log_metric(
                        correlation_id,
                        TRIE_STORE_READ_GETS,
                        GET,
                        GAUGE,
                        f64::from(get_counter),
                    );
                    log_duration(
                        correlation_id,
                        TRIE_STORE_READ_DURATION,
                        READ,
                        start.elapsed(),
                    );
                    return Ok(ReadResult::NotFound);
                }
            }
        }
    }
}
/// Returns a value from the corresponding key at a given root in a given store
Returns a value from the corresponding key at a given root in a given store
Returns a value from the corresponding key at a given root in a given store
pub fn read<K, V, T, S, E>(
    correlation_id: CorrelationId,
    txn: &T,
    store: &S,
    root: &Blake2bHash,
    key: &K,
) -> Result<ReadResult<V>, E>
where
    K: ToBytes + FromBytes + Eq + std::fmt::Debug,
    V: ToBytes + FromBytes,
    T: Readable<Handle = S::Handle>,
    S: TrieStore<K, V>,
    S::Error: From<T::Error>,
    E: From<S::Error> + From<contract_ffi::bytesrepr::Error>,
{
    let path: Vec<u8> = key.to_bytes()?;
    let mut depth: usize = 0;
    let mut current: Trie<K, V> = match store.get(txn, root)? {
        Some(root) => root,
        None => return Ok(ReadResult::RootNotFound),
    };
    let start = Instant::now();
    let mut get_counter: i32 = 0;
    loop {
        match current {
            Trie::Leaf {
                key: leaf_key,
                value: leaf_value,
            } => {
                let result = if *key == leaf_key {
                    ReadResult::Found(leaf_value)
                } else {
                    // Keys may not match in the case of a compressed path from
                    // a Node directly to a Leaf
                    ReadResult::NotFound
                };
                log_metric(
                    correlation_id,
                    TRIE_STORE_READ_GETS,
                    GET,
                    GAUGE,
                    f64::from(get_counter),
                );
                log_duration(
                    correlation_id,
                    TRIE_STORE_READ_DURATION,
                    READ,
                    start.elapsed(),
                );
                return Ok(result);
            }
            Trie::Node { pointer_block } => {
                let index: usize = {
                    assert!(depth < path.len(), "depth must be < {}", path.len());
                    path[depth].into()
                };
                let maybe_pointer: Option<Pointer> = {
                    assert!(index < trie::RADIX, "key length must be < {}", trie::RADIX);
                    pointer_block[index]
                };
                match maybe_pointer {
                    Some(pointer) => match store.get(txn, pointer.hash())? {
                        Some(next) => {
                            get_counter += 1;
                            depth += 1;
                            current = next;
                        }
                        None => {
                            get_counter += 1;
                            log_metric(
                                correlation_id,
                                TRIE_STORE_READ_GETS,
                                GET,
                                GAUGE,
                                f64::from(get_counter),
                            );
                            log_duration(
                                correlation_id,
                                TRIE_STORE_READ_DURATION,
                                READ,
                                start.elapsed(),
                            );
                            panic!(
                                "No trie value at key: {:?} (reading from key: {:?})",
                                pointer.hash(),
                                key
                            );
                        }
                    },
                    None => {
                        log_metric(
                            correlation_id,
                            TRIE_STORE_READ_GETS,
                            GET,
                            GAUGE,
                            f64::from(get_counter),
                        );
                        log_duration(
                            correlation_id,
                            TRIE_STORE_READ_DURATION,
                            READ,
                            start.elapsed(),
                        );
                        return Ok(ReadResult::NotFound);
                    }
                }
            }
            Trie::Extension { affix, pointer } => {
                let sub_path = &path[depth..depth + affix.len()];
                if sub_path == affix.as_slice() {
                    get_counter += 1;
                    match store.get(txn, pointer.hash())? {
                        Some(next) => {
                            get_counter += 1;
                            depth += affix.len();
                            current = next;
                        }
                        None => {
                            get_counter += 1;
                            log_metric(
                                correlation_id,
                                TRIE_STORE_READ_GETS,
                                GET,
                                GAUGE,
                                f64::from(get_counter),
                            );
                            log_duration(
                                correlation_id,
                                TRIE_STORE_READ_DURATION,
                                READ,
                                start.elapsed(),
                            );
                            panic!(
                                "No trie value at key: {:?} (reading from key: {:?})",
                                pointer.hash(),
                                key
                            );
                        }
                    }
                } else {
                    log_metric(
                        correlation_id,
                        TRIE_STORE_READ_GETS,
                        GET,
                        GAUGE,
                        f64::from(get_counter),
                    );
                    log_duration(
                        correlation_id,
                        TRIE_STORE_READ_DURATION,
                        READ,
                        start.elapsed(),
                    );
                    return Ok(ReadResult::NotFound);
                }
            }
        }
    }
}
pub fn read < K , V , T , S , E > ( correlation_id : CorrelationId , txn : & T , store : & S , root : & Blake2bHash , key : & K , ) -> Result < ReadResult < V > , E > where K : ToBytes + FromBytes + Eq + std :: fmt :: Debug , V : ToBytes + FromBytes , T : Readable < Handle = S :: Handle > , S : TrieStore < K , V > , S :: Error : From < T :: Error > , E : From < S :: Error > + From < contract_ffi :: bytesrepr :: Error > , { let path : Vec < u8 > = key . to_bytes ( ) ? ; let mut depth : usize = 0 ; let mut current : Trie < K , V > = match store . get ( txn , root ) ? { Some ( root ) => root , None => return Ok ( ReadResult :: RootNotFound ) , } ; let start = Instant :: now ( ) ; let mut get_counter : i32 = 0 ; loop { match current { Trie :: Leaf { key : leaf_key , value : leaf_value , } => { let result = if * key == leaf_key { ReadResult :: Found ( leaf_value ) } else { // Keys may not match in the case of a compressed path from // a Node directly to a Leaf ReadResult :: NotFound } ; log_metric ( correlation_id , TRIE_STORE_READ_GETS , GET , GAUGE , f64 :: from ( get_counter ) , ) ; log_duration ( correlation_id , TRIE_STORE_READ_DURATION , READ , start . elapsed ( ) , ) ; return Ok ( result ) ; } Trie :: Node { pointer_block } => { let index : usize = { assert ! ( depth path len ( ) " " path len ( ) ) ; path [ depth ] . into ( ) } ; let maybe_pointer : Option < Pointer > = { assert ! ( index trie RADIX " " trie RADIX ) ; pointer_block [ index ] } ; match maybe_pointer { Some ( pointer ) => match store . get ( txn , pointer . hash ( ) ) ? { Some ( next ) => { get_counter += 1 ; depth += 1 ; current = next ; } None => { get_counter += 1 ; log_metric ( correlation_id , TRIE_STORE_READ_GETS , GET , GAUGE , f64 :: from ( get_counter ) , ) ; log_duration ( correlation_id , TRIE_STORE_READ_DURATION , READ , start . elapsed ( ) , ) ; panic ! ( " " pointer hash ( ) key ) ; } } , None => { log_metric ( correlation_id , TRIE_STORE_READ_GETS , GET , GAUGE , f64 :: from ( get_counter ) , ) ; log_duration ( correlation_id , TRIE_STORE_READ_DURATION , READ , start . elapsed ( ) , ) ; return Ok ( ReadResult :: NotFound ) ; } } } Trie :: Extension { affix , pointer } => { let sub_path = & path [ depth .. depth + affix . len ( ) ] ; if sub_path == affix . as_slice ( ) { get_counter += 1 ; match store . get ( txn , pointer . hash ( ) ) ? { Some ( next ) => { get_counter += 1 ; depth += affix . len ( ) ; current = next ; } None => { get_counter += 1 ; log_metric ( correlation_id , TRIE_STORE_READ_GETS , GET , GAUGE , f64 :: from ( get_counter ) , ) ; log_duration ( correlation_id , TRIE_STORE_READ_DURATION , READ , start . elapsed ( ) , ) ; panic ! ( " " pointer hash ( ) key ) ; } } } else { log_metric ( correlation_id , TRIE_STORE_READ_GETS , GET , GAUGE , f64 :: from ( get_counter ) , ) ; log_duration ( correlation_id , TRIE_STORE_READ_DURATION , READ , start . elapsed ( ) , ) ; return Ok ( ReadResult :: NotFound ) ; } } } } }
Returns a value from the corresponding key at a given root in a given store
Returns a value from the corresponding key at a given root in a given store
correlation_id
CorrelationId
txn
&T
store
&S
root
&Blake2bHash
key
&K
correlation_id
CorrelationId
txn
&T
store
&S
root
&Blake2bHash
key
&K