Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
ismellike committed Sep 27, 2022
2 parents bd08192 + 6b7c704 commit 9b051c4
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 0 deletions.
53 changes: 53 additions & 0 deletions packages/storage-plus/src/indexed_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,34 @@ where
fn no_prefix_raw(&self) -> Prefix<Vec<u8>, T, K> {
Prefix::new(self.pk_namespace, &[])
}

/// Clears the map, removing all elements.
pub fn clear(&self, store: &mut dyn Storage) {
const TAKE: usize = 10;
let mut cleared = false;

while !cleared {
let paths = self
.no_prefix_raw()
.keys_raw(store, None, None, cosmwasm_std::Order::Ascending)
.map(|raw_key| Path::<T>::new(self.pk_namespace, &[raw_key.as_slice()]))
// Take just TAKE elements to prevent possible heap overflow if the Map is big.
.take(TAKE)
.collect::<Vec<_>>();

paths.iter().for_each(|path| store.remove(path));

cleared = paths.len() < TAKE;
}
}

/// Returns `true` if the map is empty.
pub fn is_empty(&self, store: &dyn Storage) -> bool {
self.no_prefix_raw()
.keys_raw(store, None, None, cosmwasm_std::Order::Ascending)
.next()
.is_none()
}
}

#[cfg(feature = "iterator")]
Expand Down Expand Up @@ -1679,4 +1707,29 @@ mod test {
);
}
}

#[test]
fn clear_works() {
let mut storage = MockStorage::new();
let map = build_map();
let (pks, _) = save_data(&mut storage, &map);

map.clear(&mut storage);

for key in pks {
assert!(!map.has(&storage, key));
}
}

#[test]
fn is_empty_works() {
let mut storage = MockStorage::new();
let map = build_map();

assert!(map.is_empty(&storage));

save_data(&mut storage, &map);

assert!(!map.is_empty(&storage));
}
}
66 changes: 66 additions & 0 deletions packages/storage-plus/src/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,36 @@ where
from_slice(&result).map(Some)
}
}

/// Clears the map, removing all elements.
#[cfg(feature = "iterator")]
pub fn clear(&self, store: &mut dyn Storage) {
const TAKE: usize = 10;
let mut cleared = false;

while !cleared {
let paths = self
.no_prefix_raw()
.keys_raw(store, None, None, cosmwasm_std::Order::Ascending)
.map(|raw_key| Path::<T>::new(self.namespace, &[raw_key.as_slice()]))
// Take just TAKE elements to prevent possible heap overflow if the Map is big.
.take(TAKE)
.collect::<Vec<_>>();

paths.iter().for_each(|path| store.remove(path));

cleared = paths.len() < TAKE;
}
}

/// Returns `true` if the map is empty.
#[cfg(feature = "iterator")]
pub fn is_empty(&self, store: &dyn Storage) -> bool {
self.no_prefix_raw()
.keys_raw(store, None, None, cosmwasm_std::Order::Ascending)
.next()
.is_none()
}
}

#[cfg(feature = "iterator")]
Expand Down Expand Up @@ -1511,4 +1541,40 @@ mod test {
assert_eq!(include.len(), 1);
assert_eq!(include, vec![456]);
}

#[test]
#[cfg(feature = "iterator")]
fn clear_works() {
const TEST_MAP: Map<&str, u32> = Map::new("test_map");

let mut storage = MockStorage::new();
TEST_MAP.save(&mut storage, "key0", &0u32).unwrap();
TEST_MAP.save(&mut storage, "key1", &1u32).unwrap();
TEST_MAP.save(&mut storage, "key2", &2u32).unwrap();
TEST_MAP.save(&mut storage, "key3", &3u32).unwrap();
TEST_MAP.save(&mut storage, "key4", &4u32).unwrap();

TEST_MAP.clear(&mut storage);

assert!(!TEST_MAP.has(&storage, "key0"));
assert!(!TEST_MAP.has(&storage, "key1"));
assert!(!TEST_MAP.has(&storage, "key2"));
assert!(!TEST_MAP.has(&storage, "key3"));
assert!(!TEST_MAP.has(&storage, "key4"));
}

#[test]
#[cfg(feature = "iterator")]
fn is_empty_works() {
const TEST_MAP: Map<&str, u32> = Map::new("test_map");

let mut storage = MockStorage::new();

assert!(TEST_MAP.is_empty(&storage));

TEST_MAP.save(&mut storage, "key1", &1u32).unwrap();
TEST_MAP.save(&mut storage, "key2", &2u32).unwrap();

assert!(!TEST_MAP.is_empty(&storage));
}
}

0 comments on commit 9b051c4

Please sign in to comment.