Skip to content

Commit

Permalink
Rename OwnedBound -> Bound and use Option<Bound> as args
Browse files Browse the repository at this point in the history
  • Loading branch information
ethanfrey committed Oct 16, 2020
1 parent 9908507 commit 2bcf6cf
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 116 deletions.
6 changes: 3 additions & 3 deletions packages/storage-plus/src/indexes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use cosmwasm_std::{Binary, Order, StdError, StdResult, Storage, KV};

use crate::map::Map;
use crate::prefix::range_with_prefix;
use crate::{Bound, Endian};
use crate::Endian;

/// MARKER is stored in the multi-index as value, but we only look at the key (which is pk)
const MARKER: u32 = 1;
Expand Down Expand Up @@ -86,8 +86,8 @@ where
{
pub fn pks<'c>(&self, store: &'c S, idx: &[u8]) -> Box<dyn Iterator<Item = Vec<u8>> + 'c> {
let prefix = self.idx_map.prefix(idx);
let mapped = range_with_prefix(store, &prefix, Bound::None, Bound::None, Order::Ascending)
.map(|(k, _)| k);
let mapped =
range_with_prefix(store, &prefix, None, None, Order::Ascending).map(|(k, _)| k);
Box::new(mapped)
}

Expand Down
2 changes: 1 addition & 1 deletion packages/storage-plus/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ pub use keys::{PkOwned, Prefixer, PrimaryKey, U128Key, U16Key, U32Key, U64Key};
pub use map::Map;
pub use path::Path;
#[cfg(feature = "iterator")]
pub use prefix::{Bound, OwnedBound, Prefix};
pub use prefix::{Bound, Prefix};
24 changes: 10 additions & 14 deletions packages/storage-plus/src/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ where
pub fn range<'c, S: Storage>(
&self,
store: &'c S,
min: Bound<'_>,
max: Bound<'_>,
min: Option<Bound>,
max: Option<Bound>,
order: cosmwasm_std::Order,
) -> Box<dyn Iterator<Item = StdResult<cosmwasm_std::KV<T>>> + 'c>
where
Expand Down Expand Up @@ -200,9 +200,7 @@ mod test {
PEOPLE.save(&mut store, b"jim", &data2).unwrap();

// let's try to iterate!
let all: StdResult<Vec<_>> = PEOPLE
.range(&store, Bound::None, Bound::None, Order::Ascending)
.collect();
let all: StdResult<Vec<_>> = PEOPLE.range(&store, None, None, Order::Ascending).collect();
let all = all.unwrap();
assert_eq!(2, all.len());
assert_eq!(
Expand Down Expand Up @@ -230,7 +228,7 @@ mod test {
// let's try to iterate!
let all: StdResult<Vec<_>> = ALLOWANCE
.prefix(b"owner")
.range(&store, Bound::None, Bound::None, Order::Ascending)
.range(&store, None, None, Order::Ascending)
.collect();
let all = all.unwrap();
assert_eq!(2, all.len());
Expand Down Expand Up @@ -384,9 +382,7 @@ mod test {
PEOPLE.save(&mut store, b"jim", &data2)?;

// iterate over them all
let all: StdResult<Vec<_>> = PEOPLE
.range(&store, Bound::None, Bound::None, Order::Ascending)
.collect();
let all: StdResult<Vec<_>> = PEOPLE.range(&store, None, None, Order::Ascending).collect();
assert_eq!(
all?,
vec![(b"jim".to_vec(), data2), (b"john".to_vec(), data.clone())]
Expand All @@ -396,8 +392,8 @@ mod test {
let all: StdResult<Vec<_>> = PEOPLE
.range(
&store,
Bound::Exclusive(b"jim"),
Bound::None,
Some(Bound::Exclusive(b"jim".to_vec())),
None,
Order::Ascending,
)
.collect();
Expand All @@ -411,7 +407,7 @@ mod test {
// get all under one key
let all: StdResult<Vec<_>> = ALLOWANCE
.prefix(b"owner")
.range(&store, Bound::None, Bound::None, Order::Ascending)
.range(&store, None, None, Order::Ascending)
.collect();
assert_eq!(
all?,
Expand All @@ -423,8 +419,8 @@ mod test {
.prefix(b"owner")
.range(
&store,
Bound::Exclusive(b"spender1"),
Bound::Inclusive(b"spender2"),
Some(Bound::Exclusive(b"spender1".to_vec())),
Some(Bound::Inclusive(b"spender2".to_vec())),
Order::Descending,
)
.collect();
Expand Down
160 changes: 62 additions & 98 deletions packages/storage-plus/src/prefix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,32 @@ use crate::Endian;
/// None means that we don't limit that side of the range at all.
/// Include means we use the given bytes as a limit and *include* anything at that exact key
/// Exclude means we use the given bytes as a limit and *exclude* anything at that exact key
#[derive(Copy, Clone, Debug)]
pub enum Bound<'a> {
Inclusive(&'a [u8]),
Exclusive(&'a [u8]),
None,
#[derive(Clone, Debug)]
pub enum Bound {
Inclusive(Vec<u8>),
Exclusive(Vec<u8>),
}

impl Bound {
/// Turns optional binary, like Option<CanonicalAddr> into an inclusive bound
pub fn inclusive<T: Into<Vec<u8>>>(limit: T) -> Self {
Bound::Inclusive(limit.into())
}

/// Turns optional binary, like Option<CanonicalAddr> into an exclusive bound
pub fn exclusive<T: Into<Vec<u8>>>(limit: T) -> Self {
Bound::Exclusive(limit.into())
}

/// Turns an int, like Option<u32> into an inclusive bound
pub fn inclusive_int<T: Endian>(limit: T) -> Self {
Bound::Inclusive(limit.to_be_bytes().into())
}

/// Turns an int, like Option<u64> into an exclusive bound
pub fn exclusive_int<T: Endian>(limit: T) -> Self {
Bound::Exclusive(limit.to_be_bytes().into())
}
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -59,8 +80,8 @@ where
pub fn range<'a, S: Storage>(
&self,
store: &'a S,
min: Bound<'_>,
max: Bound<'_>,
min: Option<Bound>,
max: Option<Bound>,
order: Order,
) -> Box<dyn Iterator<Item = StdResult<KV<T>>> + 'a>
where
Expand All @@ -72,68 +93,15 @@ where
}
}

/// OwnedBound is like bound, but owns the data (as a Vec<u8>) inside.
/// It is much easier to use if you dynamically construct the content, and can be passed into range as well.
/// We provide lots of helpers to create these bounds from other data-types
#[derive(Clone, Debug)]
pub enum OwnedBound {
Inclusive(Vec<u8>),
Exclusive(Vec<u8>),
None,
}

impl OwnedBound {
/// Returns a bound that borrows the owned data, to pass into range()
pub fn bound(&self) -> Bound<'_> {
match self {
OwnedBound::Inclusive(limit) => Bound::Inclusive(&limit),
OwnedBound::Exclusive(limit) => Bound::Exclusive(&limit),
OwnedBound::None => Bound::None,
}
}

/// Turns optional binary, like Option<CanonicalAddr> into an inclusive bound
pub fn inclusive<T: Into<Vec<u8>>>(maybe: Option<T>) -> Self {
match maybe {
Some(bytes) => OwnedBound::Inclusive(bytes.into()),
None => OwnedBound::None,
}
}

/// Turns optional binary, like Option<CanonicalAddr> into an exclusive bound
pub fn exclusive<T: Into<Vec<u8>>>(maybe: Option<T>) -> Self {
match maybe {
Some(bytes) => OwnedBound::Exclusive(bytes.into()),
None => OwnedBound::None,
}
}

/// Turns an int, like Option<u32> into an inclusive bound
pub fn inclusive_int<T: Endian>(limit: Option<T>) -> Self {
match limit {
Some(t) => Self::Inclusive(t.to_be_bytes().into()),
None => OwnedBound::None,
}
}

/// Turns an int, like Option<u64> into an exclusive bound
pub fn exclusive_int<T: Endian>(limit: Option<T>) -> Self {
match limit {
Some(t) => Self::Exclusive(t.to_be_bytes().into()),
None => OwnedBound::None,
}
}
}

pub(crate) fn range_with_prefix<'a, S: Storage>(
storage: &'a S,
namespace: &[u8],
start: Bound<'_>,
end: Bound<'_>,
start: Option<Bound>,
end: Option<Bound>,
order: Order,
) -> Box<dyn Iterator<Item = KV> + 'a> {
let start = calc_start_bound(namespace, start, order);
let end = calc_end_bound(namespace, end, order);
let start = calc_start_bound(namespace, start);
let end = calc_end_bound(namespace, end);

// get iterator from storage
let base_iterator = storage.range(Some(&start), Some(&end), order);
Expand All @@ -144,23 +112,21 @@ pub(crate) fn range_with_prefix<'a, S: Storage>(
Box::new(mapped)
}

// TODO: does order matter here?
fn calc_start_bound(namespace: &[u8], bound: Bound<'_>, _order: Order) -> Vec<u8> {
fn calc_start_bound(namespace: &[u8], bound: Option<Bound>) -> Vec<u8> {
match bound {
Bound::None => namespace.to_vec(),
None => namespace.to_vec(),
// this is the natural limits of the underlying Storage
Bound::Inclusive(limit) => concat(namespace, limit),
Bound::Exclusive(limit) => concat(namespace, &one_byte_higher(limit)),
Some(Bound::Inclusive(limit)) => concat(namespace, &limit),
Some(Bound::Exclusive(limit)) => concat(namespace, &one_byte_higher(&limit)),
}
}

// TODO: does order matter here?
fn calc_end_bound(namespace: &[u8], bound: Bound<'_>, _order: Order) -> Vec<u8> {
fn calc_end_bound(namespace: &[u8], bound: Option<Bound>) -> Vec<u8> {
match bound {
Bound::None => namespace_upper_bound(namespace),
None => namespace_upper_bound(namespace),
// this is the natural limits of the underlying Storage
Bound::Exclusive(limit) => concat(namespace, limit),
Bound::Inclusive(limit) => concat(namespace, &one_byte_higher(limit)),
Some(Bound::Exclusive(limit)) => concat(namespace, &limit),
Some(Bound::Inclusive(limit)) => concat(namespace, &one_byte_higher(&limit)),
}
}

Expand Down Expand Up @@ -217,21 +183,19 @@ mod test {
let expected_reversed: Vec<(Vec<u8>, u64)> = expected.iter().rev().cloned().collect();

// let's do the basic sanity check
let res: StdResult<Vec<_>> = prefix
.range(&store, Bound::None, Bound::None, Order::Ascending)
.collect();
let res: StdResult<Vec<_>> = prefix.range(&store, None, None, Order::Ascending).collect();
assert_eq!(&expected, &res.unwrap());
let res: StdResult<Vec<_>> = prefix
.range(&store, Bound::None, Bound::None, Order::Descending)
.range(&store, None, None, Order::Descending)
.collect();
assert_eq!(&expected_reversed, &res.unwrap());

// now let's check some ascending ranges
let res: StdResult<Vec<_>> = prefix
.range(
&store,
Bound::Inclusive(b"ra"),
Bound::None,
Some(Bound::Inclusive(b"ra".to_vec())),
None,
Order::Ascending,
)
.collect();
Expand All @@ -240,8 +204,8 @@ mod test {
let res: StdResult<Vec<_>> = prefix
.range(
&store,
Bound::Exclusive(b"ra"),
Bound::None,
Some(Bound::Exclusive(b"ra".to_vec())),
None,
Order::Ascending,
)
.collect();
Expand All @@ -250,8 +214,8 @@ mod test {
let res: StdResult<Vec<_>> = prefix
.range(
&store,
Bound::Exclusive(b"r"),
Bound::None,
Some(Bound::Exclusive(b"r".to_vec())),
None,
Order::Ascending,
)
.collect();
Expand All @@ -261,8 +225,8 @@ mod test {
let res: StdResult<Vec<_>> = prefix
.range(
&store,
Bound::None,
Bound::Inclusive(b"ra"),
None,
Some(Bound::Inclusive(b"ra".to_vec())),
Order::Descending,
)
.collect();
Expand All @@ -271,8 +235,8 @@ mod test {
let res: StdResult<Vec<_>> = prefix
.range(
&store,
Bound::None,
Bound::Exclusive(b"ra"),
None,
Some(Bound::Exclusive(b"ra".to_vec())),
Order::Descending,
)
.collect();
Expand All @@ -281,8 +245,8 @@ mod test {
let res: StdResult<Vec<_>> = prefix
.range(
&store,
Bound::None,
Bound::Exclusive(b"rb"),
None,
Some(Bound::Exclusive(b"rb".to_vec())),
Order::Descending,
)
.collect();
Expand All @@ -292,8 +256,8 @@ mod test {
let res: StdResult<Vec<_>> = prefix
.range(
&store,
Bound::Inclusive(b"ra"),
Bound::Exclusive(b"zi"),
Some(Bound::Inclusive(b"ra".to_vec())),
Some(Bound::Exclusive(b"zi".to_vec())),
Order::Ascending,
)
.collect();
Expand All @@ -302,8 +266,8 @@ mod test {
let res: StdResult<Vec<_>> = prefix
.range(
&store,
Bound::Inclusive(b"ra"),
Bound::Exclusive(b"zi"),
Some(Bound::Inclusive(b"ra".to_vec())),
Some(Bound::Exclusive(b"zi".to_vec())),
Order::Descending,
)
.collect();
Expand All @@ -312,8 +276,8 @@ mod test {
let res: StdResult<Vec<_>> = prefix
.range(
&store,
Bound::Inclusive(b"ra"),
Bound::Inclusive(b"zi"),
Some(Bound::Inclusive(b"ra".to_vec())),
Some(Bound::Inclusive(b"zi".to_vec())),
Order::Descending,
)
.collect();
Expand All @@ -322,8 +286,8 @@ mod test {
let res: StdResult<Vec<_>> = prefix
.range(
&store,
Bound::Exclusive(b"ra"),
Bound::Exclusive(b"zi"),
Some(Bound::Exclusive(b"ra".to_vec())),
Some(Bound::Exclusive(b"zi".to_vec())),
Order::Ascending,
)
.collect();
Expand Down

0 comments on commit 2bcf6cf

Please sign in to comment.