cfx_storage/utils/
mod.rs

1// Copyright 2019 Conflux Foundation. All rights reserved.
2// Conflux is free software and distributed under GNU General Public License.
3// See http://www.gnu.org/licenses/
4
5#[macro_use]
6pub mod deref_plus_impl_or_borrow_self;
7#[macro_use]
8pub mod tuple;
9pub mod guarded_value;
10pub mod wrap;
11
12// TODO: add comments and unit tests
13pub fn to_key_prefix_iter_upper_bound(key_prefix: &[u8]) -> Option<Vec<u8>> {
14    let mut upper_bound_excl_value = key_prefix.to_vec();
15    if upper_bound_excl_value.len() == 0 {
16        None
17    } else {
18        let mut carry = 1;
19        let len = upper_bound_excl_value.len();
20        for i in 0..len {
21            if upper_bound_excl_value[len - 1 - i] == 255 {
22                upper_bound_excl_value[len - 1 - i] = 0;
23            } else {
24                upper_bound_excl_value[len - 1 - i] += 1;
25                carry = 0;
26                break;
27            }
28        }
29        // all bytes in lower_bound_incl are 255, which means no upper bound
30        // is needed.
31        if carry == 1 {
32            None
33        } else {
34            Some(upper_bound_excl_value)
35        }
36    }
37}
38
39pub mod access_mode {
40    pub trait AccessMode {
41        const READ_ONLY: bool;
42    }
43
44    pub struct Read;
45    pub struct Write;
46
47    impl AccessMode for Read {
48        const READ_ONLY: bool = true;
49    }
50
51    impl AccessMode for Write {
52        const READ_ONLY: bool = false;
53    }
54}
55
56/// The purpose of this trait is to create a new value of a passed object,
57/// when the passed object is the value, simply move the value;
58/// when the passed object is the reference, create the new value by clone.
59/// Other extension is possible.
60///
61/// The trait is used by ChildrenTable and slab.
62pub trait WrappedCreateFrom<FromType, ToType> {
63    fn take(x: FromType) -> ToType;
64    /// Unoptimized default implementation.
65    fn take_from(dest: &mut ToType, x: FromType) { *dest = Self::take(x); }
66}
67
68/*
69/// This is correct but we don't use this implementation.
70impl<T> WrappedCreateFrom<T, UnsafeCell<T>> for UnsafeCell<T> {
71    fn take(val: T) -> UnsafeCell<T> { UnsafeCell::new(val) }
72}
73*/
74
75impl<'x, T: Clone> WrappedCreateFrom<&'x T, UnsafeCell<T>> for UnsafeCell<T> {
76    fn take(val: &'x T) -> UnsafeCell<T> { UnsafeCell::new(val.clone()) }
77
78    fn take_from(dest: &mut UnsafeCell<T>, x: &'x T) {
79        dest.get_mut().clone_from(x);
80    }
81}
82
83pub trait UnsafeCellExtension<T: Sized> {
84    fn get_ref(&self) -> &T;
85    fn get_mut(&mut self) -> &mut T;
86    unsafe fn get_as_mut(&self) -> &mut T;
87}
88
89impl<T: Sized> UnsafeCellExtension<T> for UnsafeCell<T> {
90    fn get_ref(&self) -> &T { unsafe { &*self.get() } }
91
92    fn get_mut(&mut self) -> &mut T { unsafe { &mut *self.get() } }
93
94    unsafe fn get_as_mut(&self) -> &mut T { &mut *self.get() }
95}
96
97/// Only used by storage benchmark due to incompatibility of rlp crate version.
98pub trait StateRootWithAuxInfoToFromRlpBytes {
99    fn to_rlp_bytes(&self) -> Vec<u8>;
100    fn from_rlp_bytes(bytes: &[u8]) -> Result<StateRootWithAuxInfo>;
101}
102
103/// Only used by storage benchmark due to incompatibility of rlp crate version.
104impl StateRootWithAuxInfoToFromRlpBytes for StateRootWithAuxInfo {
105    fn to_rlp_bytes(&self) -> Vec<u8> { self.rlp_bytes() }
106
107    fn from_rlp_bytes(bytes: &[u8]) -> Result<Self> {
108        Ok(Self::decode(&Rlp::new(bytes))?)
109    }
110}
111
112use crate::Result;
113use cfx_internal_common::StateRootWithAuxInfo;
114use rlp::{Decodable, Encodable, Rlp};
115use std::cell::UnsafeCell;