Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 58 additions & 10 deletions src/indexed_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,23 +149,36 @@ where
}

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

while !cleared {
let paths = self
let entries = self
.no_prefix_raw()
.keys_raw(store, None, None, cosmwasm_std::Order::Ascending)
.map(|raw_key| Path::<T>::new(self.pk_namespace.as_slice(), &[raw_key.as_slice()]))
.range_raw(store, None, None, cosmwasm_std::Order::Ascending)
// 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;
.collect::<Result<Vec<_>, _>>();

match entries {
Ok(entries) => {
// Remove from indexes first
for (raw_key, data) in &entries {
for index in self.idx.get_indexes() {
index.remove(store, raw_key, data)?;
}
let path =
Path::<T>::new(self.pk_namespace.as_slice(), &[raw_key.as_slice()]);
store.remove(&path);
}

cleared = entries.len() < TAKE;
}
Err(e) => return Err(e),
}
}
Ok(())
}

/// Returns `true` if the map is empty.
Expand Down Expand Up @@ -1702,13 +1715,48 @@ mod test {
let mut storage = MockStorage::new();
let (pks, _) = save_data(&mut storage);

DATA.clear(&mut storage);
DATA.clear(&mut storage).unwrap();

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

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

DATA.clear(&mut storage).unwrap();

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

assert!(DATA.is_empty(&storage), "indexed map should be empty");

let count = DATA
.idx
.age
.keys_raw(&storage, None, None, Order::Ascending)
.count();
assert_eq!(count, 0, "age index should be empty");

let count = DATA
.idx
.name
.keys_raw(&storage, None, None, Order::Ascending)
.count();
assert_eq!(count, 0, "name index should be empty");

let count = DATA
.idx
.name_lastname
.keys_raw(&storage, None, None, Order::Ascending)
.count();
assert_eq!(count, 0, "name_lastname index should be empty");
}

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