Skip to content

Commit 1b621ae

Browse files
authored
Merge pull request #78 from CosmWasm/70-reverse-iteration-order
Reverse iteration order
2 parents 2203ab7 + 4fd8080 commit 1b621ae

File tree

2 files changed

+225
-30
lines changed

2 files changed

+225
-30
lines changed

packages/storey/src/containers/column.rs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,8 @@ pub enum LenError {
457457

458458
#[cfg(test)]
459459
mod tests {
460+
use crate::containers::{BoundedRevIterableAccessor as _, RevIterableAccessor as _};
461+
460462
use super::*;
461463

462464
use mocks::backend::TestStorage;
@@ -544,6 +546,34 @@ mod tests {
544546
);
545547
}
546548

549+
#[test]
550+
fn rev_iteration() {
551+
let mut storage = TestStorage::new();
552+
553+
let column = Column::<u64, TestEncoding>::new(0);
554+
let mut access = column.access(&mut storage);
555+
556+
access.push(&1337).unwrap();
557+
access.push(&42).unwrap();
558+
access.push(&9001).unwrap();
559+
access.remove(1).unwrap();
560+
561+
assert_eq!(
562+
access.rev_pairs().collect::<Result<Vec<_>, _>>().unwrap(),
563+
vec![(2, 9001), (0, 1337)]
564+
);
565+
566+
assert_eq!(
567+
access.rev_keys().collect::<Result<Vec<_>, _>>().unwrap(),
568+
vec![2, 0]
569+
);
570+
571+
assert_eq!(
572+
access.rev_values().collect::<Result<Vec<_>, _>>().unwrap(),
573+
vec![9001, 1337]
574+
);
575+
}
576+
547577
#[test]
548578
fn bounded_iteration() {
549579
let mut storage = TestStorage::new();
@@ -627,4 +657,51 @@ mod tests {
627657
vec![1337, 42, 1]
628658
);
629659
}
660+
661+
#[test]
662+
fn bounded_rev_iteration() {
663+
let mut storage = TestStorage::new();
664+
665+
let column = Column::<u64, TestEncoding>::new(0);
666+
let mut access = column.access(&mut storage);
667+
668+
access.push(&1337).unwrap();
669+
access.push(&42).unwrap();
670+
access.push(&9001).unwrap();
671+
access.push(&1).unwrap();
672+
access.push(&2).unwrap();
673+
access.remove(2).unwrap();
674+
675+
// start and end set
676+
assert_eq!(
677+
access
678+
.bounded_rev_pairs(Some(1), Some(4))
679+
.collect::<Result<Vec<_>, _>>()
680+
.unwrap(),
681+
vec![(3, 1), (1, 42)]
682+
);
683+
assert_eq!(
684+
access
685+
.bounded_rev_keys(Some(1), Some(4))
686+
.collect::<Result<Vec<_>, _>>()
687+
.unwrap(),
688+
vec![3, 1]
689+
);
690+
assert_eq!(
691+
access
692+
.bounded_rev_values(Some(1), Some(4))
693+
.collect::<Result<Vec<_>, _>>()
694+
.unwrap(),
695+
vec![1, 42]
696+
);
697+
698+
// end unset
699+
assert_eq!(
700+
access
701+
.bounded_rev_pairs(Some(1), None)
702+
.collect::<Result<Vec<_>, _>>()
703+
.unwrap(),
704+
vec![(4, 2), (3, 1), (1, 42)]
705+
);
706+
}
630707
}

packages/storey/src/containers/mod.rs

Lines changed: 148 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use std::marker::PhantomData;
1111
pub use column::{Column, ColumnAccess};
1212
pub use item::{Item, ItemAccess};
1313
pub use map::{Map, MapAccess};
14+
use storey_storage::RevIterableStorage;
1415

1516
use crate::storage::IterableStorage;
1617

@@ -84,30 +85,83 @@ pub trait IterableAccessor: Sized {
8485
fn storage(&self) -> &Self::Storage;
8586

8687
/// Iterate over key-value pairs in this collection.
87-
fn pairs(&self) -> StorableIter<'_, Self::Storable, Self::Storage> {
88+
fn pairs(
89+
&self,
90+
) -> StorableIter<Self::Storable, <Self::Storage as IterableStorage>::PairsIterator<'_>> {
8891
StorableIter {
8992
inner: self.storage().pairs(None, None),
9093
phantom: PhantomData,
9194
}
9295
}
9396

9497
/// Iterate over keys in this collection.
95-
fn keys(&self) -> StorableKeys<'_, Self::Storable, Self::Storage> {
98+
fn keys(
99+
&self,
100+
) -> StorableKeys<Self::Storable, <Self::Storage as IterableStorage>::KeysIterator<'_>> {
96101
StorableKeys {
97102
inner: self.storage().keys(None, None),
98103
phantom: PhantomData,
99104
}
100105
}
101106

102107
/// Iterate over values in this collection.
103-
fn values(&self) -> StorableValues<'_, Self::Storable, Self::Storage> {
108+
fn values(
109+
&self,
110+
) -> StorableValues<Self::Storable, <Self::Storage as IterableStorage>::ValuesIterator<'_>>
111+
{
104112
StorableValues {
105113
inner: self.storage().values(None, None),
106114
phantom: PhantomData,
107115
}
108116
}
109117
}
110118

119+
pub trait RevIterableAccessor
120+
where
121+
Self: IterableAccessor,
122+
Self::Storage: RevIterableStorage,
123+
{
124+
/// Iterate over key-value pairs in this collection in reverse order.
125+
fn rev_pairs(
126+
&self,
127+
) -> StorableIter<Self::Storable, <Self::Storage as RevIterableStorage>::RevPairsIterator<'_>>
128+
{
129+
StorableIter {
130+
inner: self.storage().rev_pairs(None, None),
131+
phantom: PhantomData,
132+
}
133+
}
134+
135+
/// Iterate over keys in this collection in reverse order.
136+
fn rev_keys(
137+
&self,
138+
) -> StorableKeys<Self::Storable, <Self::Storage as RevIterableStorage>::RevKeysIterator<'_>>
139+
{
140+
StorableKeys {
141+
inner: self.storage().rev_keys(None, None),
142+
phantom: PhantomData,
143+
}
144+
}
145+
146+
/// Iterate over values in this collection in reverse order.
147+
fn rev_values(
148+
&self,
149+
) -> StorableValues<Self::Storable, <Self::Storage as RevIterableStorage>::RevValuesIterator<'_>>
150+
{
151+
StorableValues {
152+
inner: self.storage().rev_values(None, None),
153+
phantom: PhantomData,
154+
}
155+
}
156+
}
157+
158+
impl<I> RevIterableAccessor for I
159+
where
160+
I: IterableAccessor,
161+
I::Storage: RevIterableStorage,
162+
{
163+
}
164+
111165
/// This trait extends [`IterableAccessor`] with methods for bounded iteration. Not every
112166
/// iterable collection supports it, so this trait is separate.
113167
///
@@ -129,7 +183,7 @@ pub trait BoundedIterableAccessor: IterableAccessor {
129183
&self,
130184
start: Option<B>,
131185
end: Option<B>,
132-
) -> StorableIter<'_, Self::Storable, Self::Storage>
186+
) -> StorableIter<Self::Storable, <Self::Storage as IterableStorage>::PairsIterator<'_>>
133187
where
134188
B: BoundFor<Self::Storable>,
135189
{
@@ -147,7 +201,7 @@ pub trait BoundedIterableAccessor: IterableAccessor {
147201
&self,
148202
start: Option<B>,
149203
end: Option<B>,
150-
) -> StorableKeys<'_, Self::Storable, Self::Storage>
204+
) -> StorableKeys<Self::Storable, <Self::Storage as IterableStorage>::KeysIterator<'_>>
151205
where
152206
B: BoundFor<Self::Storable>,
153207
{
@@ -165,7 +219,7 @@ pub trait BoundedIterableAccessor: IterableAccessor {
165219
&self,
166220
start: Option<B>,
167221
end: Option<B>,
168-
) -> StorableValues<'_, Self::Storable, Self::Storage>
222+
) -> StorableValues<Self::Storable, <Self::Storage as IterableStorage>::ValuesIterator<'_>>
169223
where
170224
B: BoundFor<Self::Storable>,
171225
{
@@ -179,6 +233,82 @@ pub trait BoundedIterableAccessor: IterableAccessor {
179233
}
180234
}
181235

236+
/// This trait extends [`BoundedIterableAccessor`] with methods for bounded reverse iteration.
237+
/// Not every iterable collection supports it, so this trait is separate.
238+
///
239+
/// Bounded reverse iteration allows the user to specify a start and end bound for the iteration,
240+
/// but in reverse order.
241+
///
242+
/// # Why not always support bounded reverse iteration?
243+
///
244+
/// The same reasons as for [bounded iteration](BoundedIterableAccessor) apply.
245+
pub trait BoundedRevIterableAccessor
246+
where
247+
Self: BoundedIterableAccessor,
248+
Self::Storage: RevIterableStorage,
249+
{
250+
/// Iterate over key-value pairs in this collection in reverse order, respecting the given bounds.
251+
fn bounded_rev_pairs<B>(
252+
&self,
253+
start: Option<B>,
254+
end: Option<B>,
255+
) -> StorableIter<Self::Storable, <Self::Storage as RevIterableStorage>::RevPairsIterator<'_>>
256+
where
257+
B: BoundFor<Self::Storable>,
258+
{
259+
let start = start.map(|b| b.into_bytes());
260+
let end = end.map(|b| b.into_bytes());
261+
262+
StorableIter {
263+
inner: self.storage().rev_pairs(start.as_deref(), end.as_deref()),
264+
phantom: PhantomData,
265+
}
266+
}
267+
268+
/// Iterate over keys in this collection in reverse order, respecting the given bounds.
269+
fn bounded_rev_keys<B>(
270+
&self,
271+
start: Option<B>,
272+
end: Option<B>,
273+
) -> StorableKeys<Self::Storable, <Self::Storage as RevIterableStorage>::RevKeysIterator<'_>>
274+
where
275+
B: BoundFor<Self::Storable>,
276+
{
277+
let start = start.map(|b| b.into_bytes());
278+
let end = end.map(|b| b.into_bytes());
279+
280+
StorableKeys {
281+
inner: self.storage().rev_keys(start.as_deref(), end.as_deref()),
282+
phantom: PhantomData,
283+
}
284+
}
285+
286+
/// Iterate over values in this collection in reverse order, respecting the given bounds.
287+
fn bounded_rev_values<B>(
288+
&self,
289+
start: Option<B>,
290+
end: Option<B>,
291+
) -> StorableValues<Self::Storable, <Self::Storage as RevIterableStorage>::RevValuesIterator<'_>>
292+
where
293+
B: BoundFor<Self::Storable>,
294+
{
295+
let start = start.map(|b| b.into_bytes());
296+
let end = end.map(|b| b.into_bytes());
297+
298+
StorableValues {
299+
inner: self.storage().rev_values(start.as_deref(), end.as_deref()),
300+
phantom: PhantomData,
301+
}
302+
}
303+
}
304+
305+
impl<I> BoundedRevIterableAccessor for I
306+
where
307+
I: BoundedIterableAccessor,
308+
I::Storage: RevIterableStorage,
309+
{
310+
}
311+
182312
/// A type that can be used as bounds for iteration over a given collection.
183313
///
184314
/// As an example, a collection `Foo` with string-y keys can accept both `String` and
@@ -190,19 +320,15 @@ pub trait BoundFor<T> {
190320
}
191321

192322
/// The iterator over key-value pairs in a collection.
193-
pub struct StorableIter<'i, S, B>
194-
where
195-
S: Storable,
196-
B: IterableStorage + 'i,
197-
{
198-
inner: B::PairsIterator<'i>,
323+
pub struct StorableIter<S, I> {
324+
inner: I,
199325
phantom: PhantomData<S>,
200326
}
201327

202-
impl<'i, S, B> Iterator for StorableIter<'i, S, B>
328+
impl<S, I> Iterator for StorableIter<S, I>
203329
where
204330
S: Storable,
205-
B: IterableStorage + 'i,
331+
I: Iterator<Item = (Vec<u8>, Vec<u8>)>,
206332
{
207333
type Item = Result<(S::Key, S::Value), KVDecodeError<S::KeyDecodeError, S::ValueDecodeError>>;
208334

@@ -218,19 +344,15 @@ where
218344
}
219345

220346
/// The iterator over keys in a collection.
221-
pub struct StorableKeys<'i, S, B>
222-
where
223-
S: Storable,
224-
B: IterableStorage + 'i,
225-
{
226-
inner: B::KeysIterator<'i>,
347+
pub struct StorableKeys<S, I> {
348+
inner: I,
227349
phantom: PhantomData<S>,
228350
}
229351

230-
impl<'i, S, B> Iterator for StorableKeys<'i, S, B>
352+
impl<S, I> Iterator for StorableKeys<S, I>
231353
where
232354
S: Storable,
233-
B: IterableStorage + 'i,
355+
I: Iterator<Item = Vec<u8>>,
234356
{
235357
type Item = Result<S::Key, S::KeyDecodeError>;
236358

@@ -240,19 +362,15 @@ where
240362
}
241363

242364
/// The iterator over values in a collection.
243-
pub struct StorableValues<'i, S, B>
244-
where
245-
S: Storable,
246-
B: IterableStorage + 'i,
247-
{
248-
inner: B::ValuesIterator<'i>,
365+
pub struct StorableValues<S, I> {
366+
inner: I,
249367
phantom: PhantomData<S>,
250368
}
251369

252-
impl<'i, S, B> Iterator for StorableValues<'i, S, B>
370+
impl<S, I> Iterator for StorableValues<S, I>
253371
where
254372
S: Storable,
255-
B: IterableStorage + 'i,
373+
I: Iterator<Item = Vec<u8>>,
256374
{
257375
type Item = Result<S::Value, S::ValueDecodeError>;
258376

0 commit comments

Comments
 (0)