diff --git a/aptos-move/framework/aptos-stdlib/doc/ordered_map.md b/aptos-move/framework/aptos-stdlib/doc/ordered_map.md index 52e6637fcc356..1693211539641 100644 --- a/aptos-move/framework/aptos-stdlib/doc/ordered_map.md +++ b/aptos-move/framework/aptos-stdlib/doc/ordered_map.md @@ -28,15 +28,19 @@ lexicographical sorting for complex types. - [Enum `Iterator`](#0x1_ordered_map_Iterator) - [Constants](#@Constants_0) - [Function `new`](#0x1_ordered_map_new) +- [Function `new_from`](#0x1_ordered_map_new_from) - [Function `length`](#0x1_ordered_map_length) - [Function `is_empty`](#0x1_ordered_map_is_empty) - [Function `add`](#0x1_ordered_map_add) - [Function `upsert`](#0x1_ordered_map_upsert) - [Function `remove`](#0x1_ordered_map_remove) - [Function `contains`](#0x1_ordered_map_contains) +- [Function `borrow`](#0x1_ordered_map_borrow) +- [Function `borrow_mut`](#0x1_ordered_map_borrow_mut) - [Function `replace_key_inplace`](#0x1_ordered_map_replace_key_inplace) +- [Function `add_all`](#0x1_ordered_map_add_all) - [Function `append`](#0x1_ordered_map_append) -- [Function `split_off`](#0x1_ordered_map_split_off) +- [Function `trim`](#0x1_ordered_map_trim) - [Function `lower_bound`](#0x1_ordered_map_lower_bound) - [Function `find`](#0x1_ordered_map_find) - [Function `new_begin_iter`](#0x1_ordered_map_new_begin_iter) @@ -52,6 +56,10 @@ lexicographical sorting for complex types. - [Function `iter_remove`](#0x1_ordered_map_iter_remove) - [Function `iter_replace`](#0x1_ordered_map_iter_replace) - [Function `destroy_empty`](#0x1_ordered_map_destroy_empty) +- [Function `keys`](#0x1_ordered_map_keys) +- [Function `values`](#0x1_ordered_map_values) +- [Function `to_vec_pair`](#0x1_ordered_map_to_vec_pair) +- [Function `destroy`](#0x1_ordered_map_destroy) - [Function `for_each_ref`](#0x1_ordered_map_for_each_ref) - [Function `for_each_mut`](#0x1_ordered_map_for_each_mut) - [Function `new_iter`](#0x1_ordered_map_new_iter) @@ -266,6 +274,34 @@ Creates a new empty OrderedMap, using default (SortedVectorMap) implementation. + + + + +## Function `new_from` + +Create a OrderedMap from a vector of keys and values. +Aborts with EKEY_ALREADY_EXISTS if duplicate keys are passed in. + + +
public fun new_from<K, V>(keys: vector<K>, values: vector<V>): ordered_map::OrderedMap<K, V>
+
+ + + +
+Implementation + + +
public fun new_from<K, V>(keys: vector<K>, values: vector<V>): OrderedMap<K, V> {
+    let map = new();
+    add_all(&mut map, keys, values);
+    map
+}
+
+ + +
@@ -435,7 +471,55 @@ Returns whether map contains a given key.
public fun contains<K, V>(self: &OrderedMap<K, V>, key: &K): bool {
-    !self.find(key).iter_is_end()
+    !self.find(key).iter_is_end(self)
+}
+
+ + + + + + + +## Function `borrow` + + + +
public fun borrow<K, V>(self: &ordered_map::OrderedMap<K, V>, key: &K): &V
+
+ + + +
+Implementation + + +
public fun borrow<K, V>(self: &OrderedMap<K, V>, key: &K): &V {
+    self.find(key).iter_borrow(self)
+}
+
+ + + +
+ + + +## Function `borrow_mut` + + + +
public fun borrow_mut<K, V>(self: &mut ordered_map::OrderedMap<K, V>, key: &K): &mut V
+
+ + + +
+Implementation + + +
public fun borrow_mut<K, V>(self: &mut OrderedMap<K, V>, key: &K): &mut V {
+    self.find(key).iter_borrow_mut(self)
 }
 
@@ -467,14 +551,14 @@ Aborts with ENEW_KEY_NOT_IN_ORDER if new_key doesn't keep the order assert!(index < len, error::invalid_argument(EKEY_NOT_FOUND)); if (index > 0) { - assert!(cmp::compare(&self.entries[index - 1].key, &new_key).is_less_than(), error::invalid_argument(ENEW_KEY_NOT_IN_ORDER)) + assert!(cmp::compare(&self.entries[index - 1].key, &new_key).is_lt(), error::invalid_argument(ENEW_KEY_NOT_IN_ORDER)) }; if (index + 1 < len) { - assert!(cmp::compare(&new_key, &self.entries[index + 1].key).is_less_than(), error::invalid_argument(ENEW_KEY_NOT_IN_ORDER)) + assert!(cmp::compare(&new_key, &self.entries[index + 1].key).is_lt(), error::invalid_argument(ENEW_KEY_NOT_IN_ORDER)) }; - let entry = self.entries.borrow_mut(index); + let entry = self.entries.borrow_mut(index); assert!(old_key == &entry.key, error::invalid_argument(EKEY_NOT_FOUND)); entry.key = new_key; } @@ -482,6 +566,34 @@ Aborts with ENEW_KEY_NOT_IN_ORDER if new_key doesn't keep the order +
+ + + +## Function `add_all` + +Add multiple key/value pairs to the map. The keys must not already exist. +Aborts with EKEY_ALREADY_EXISTS if key already exist, or duplicate keys are passed in. + + +
public fun add_all<K, V>(self: &mut ordered_map::OrderedMap<K, V>, keys: vector<K>, values: vector<V>)
+
+ + + +
+Implementation + + +
public fun add_all<K, V>(self: &mut OrderedMap<K, V>, keys: vector<K>, values: vector<V>) {
+    vector::zip(keys, values, |key, value| {
+        add(self, key, value);
+    });
+}
+
+ + +
@@ -489,6 +601,7 @@ Aborts with ENEW_KEY_NOT_IN_ORDER if new_key doesn't keep the order ## Function `append` Takes all elements from other and adds them to self. +Aborts with EKEY_ALREADY_EXISTS if other has a key already present in self.
public fun append<K, V>(self: &mut ordered_map::OrderedMap<K, V>, other: ordered_map::OrderedMap<K, V>)
@@ -516,18 +629,41 @@ Takes all elements from other and adds them to self.
     };
 
     // Optimization: if all elements in `other` are larger than all elements in `self`, we can just move them over.
-    if (cmp::compare(&self.entries.borrow(self.entries.length() - 1).key, &other_entries.borrow(0).key).is_less_than()) {
+    if (cmp::compare(&self.entries.borrow(self.entries.length() - 1).key, &other_entries.borrow(0).key).is_lt()) {
         self.entries.append(other_entries);
         return;
     };
 
-    // TODO: can be implemented more efficiently, as we know both maps are already sorted.
-    while (!other_entries.is_empty()) {
-        let Entry { key, value } = other_entries.pop_back();
-        self.add(key, value);
+    // In O(n), traversing from the back, build reverse sorted result, and then reverse it back
+    let reverse_result = vector::empty();
+    let cur_i = self.entries.length() - 1;
+    let other_i = other_entries.length() - 1;
+
+    // after the end of the loop, entries is empty, and any leftover is in other_entries
+    loop {
+        let ord = cmp::compare(&self.entries[cur_i].key, &other_entries[other_i].key);
+        assert!(!ord.is_eq(), error::invalid_argument(EKEY_ALREADY_EXISTS));
+        if (ord.is_gt()) {
+            reverse_result.push_back(self.entries.pop_back());
+            if (cur_i == 0) {
+                break;
+            } else {
+                cur_i = cur_i - 1;
+            }
+        } else {
+            reverse_result.push_back(other_entries.pop_back());
+            if (other_i == 0) {
+                // make entries empty, and rest in other_entries.
+                mem::swap(&mut other_entries, &mut self.entries);
+                break;
+            } else {
+                other_i = other_i - 1;
+            }
+        };
     };
 
-    other_entries.destroy_empty();
+    reverse_result.reverse_append(other_entries);
+    self.entries.reverse_append(reverse_result);
 }
 
@@ -535,9 +671,9 @@ Takes all elements from other and adds them to self. - + -## Function `split_off` +## Function `trim` Splits the collection into two, such to leave self with at number of elements. Returns a newly allocated map containing the elements in the range [at, len). @@ -545,7 +681,7 @@ After the call, the original map will be left containing the elements [0, at) with its previous capacity unchanged. -
public fun split_off<K, V>(self: &mut ordered_map::OrderedMap<K, V>, at: u64): ordered_map::OrderedMap<K, V>
+
public fun trim<K, V>(self: &mut ordered_map::OrderedMap<K, V>, at: u64): ordered_map::OrderedMap<K, V>
 
@@ -554,8 +690,8 @@ with its previous capacity unchanged. Implementation -
public fun split_off<K, V>(self: &mut OrderedMap<K, V>, at: u64): OrderedMap<K, V> {
-    let rest = self.entries.split_off(at);
+
public fun trim<K, V>(self: &mut OrderedMap<K, V>, at: u64): OrderedMap<K, V> {
+    let rest = self.entries.trim(at);
 
     OrderedMap::SortedVectorMap {
         entries: rest
@@ -620,7 +756,7 @@ iterator if the key is not found.
 
 
public fun find<K, V>(self: &OrderedMap<K, V>, key: &K): Iterator {
     let lower_bound = self.lower_bound(key);
-    if (lower_bound.iter_is_end()) {
+    if (lower_bound.iter_is_end(self)) {
         lower_bound
     } else if (lower_bound.iter_borrow_key(self) == key) {
         lower_bound
@@ -706,7 +842,7 @@ Note: Requires that the map is not changed after the input iterator is generated
 
 
 
public fun iter_next<K, V>(self: Iterator, map: &OrderedMap<K, V>): Iterator {
-    assert!(!self.iter_is_end(), error::invalid_argument(EITER_OUT_OF_BOUNDS));
+    assert!(!self.iter_is_end(map), error::invalid_argument(EITER_OUT_OF_BOUNDS));
 
     let index = self.index + 1;
     if (index < map.entries.length()) {
@@ -822,7 +958,7 @@ This method doesn't require having access to map, unlike iter_is_begin.
 Returns whether the iterator is an end iterator.
 
 
-
public fun iter_is_end(self: &ordered_map::Iterator): bool
+
public fun iter_is_end<K, V>(self: &ordered_map::Iterator, _map: &ordered_map::OrderedMap<K, V>): bool
 
@@ -831,7 +967,7 @@ Returns whether the iterator is an end iterator. Implementation -
public fun iter_is_end(self: &Iterator): bool {
+
public fun iter_is_end<K, V>(self: &Iterator, _map: &OrderedMap<K, V>): bool {
     self is Iterator::End
 }
 
@@ -860,7 +996,7 @@ Note: Requires that the map is not changed after the input iterator is generated
public fun iter_borrow_key<K, V>(self: &Iterator, map: &OrderedMap<K, V>): &K {
     assert!(!(self is Iterator::End), error::invalid_argument(EITER_OUT_OF_BOUNDS));
 
-    &map.entries.borrow(self.index).key
+    &map.entries.borrow(self.index).key
 }
 
@@ -887,7 +1023,7 @@ Note: Requires that the map is not changed after the input iterator is generated
public fun iter_borrow<K, V>(self: Iterator, map: &OrderedMap<K, V>): &V {
     assert!(!(self is Iterator::End), error::invalid_argument(EITER_OUT_OF_BOUNDS));
-    &map.entries.borrow(self.index).value
+    &map.entries.borrow(self.index).value
 }
 
@@ -914,7 +1050,7 @@ Note: Requires that the map is not changed after the input iterator is generated
public fun iter_borrow_mut<K, V>(self: Iterator, map: &mut OrderedMap<K, V>): &mut V {
     assert!(!(self is Iterator::End), error::invalid_argument(EITER_OUT_OF_BOUNDS));
-    &mut map.entries.borrow_mut(self.index).value
+    &mut map.entries.borrow_mut(self.index).value
 }
 
@@ -973,7 +1109,7 @@ Note: Requires that the map is not changed after the input iterator is generated
public fun iter_replace<K, V>(self: Iterator, map: &mut OrderedMap<K, V>, value: V): V {
     assert!(!(self is Iterator::End), error::invalid_argument(EKEY_NOT_FOUND));
 
-    let entry = map.entries.borrow_mut(self.index);
+    let entry = map.entries.borrow_mut(self.index);
     mem::replace(&mut entry.value, value)
 }
 
@@ -1008,6 +1144,128 @@ Aborts if self is not empty. + + + + +## Function `keys` + +Return all keys in the map. This requires keys to be copyable. + + +
public fun keys<K: copy, V>(self: &ordered_map::OrderedMap<K, V>): vector<K>
+
+ + + +
+Implementation + + +
public fun keys<K: copy, V>(self: &OrderedMap<K, V>): vector<K> {
+    vector::map_ref(&self.entries, |e| {
+        let e: &Entry<K, V> = e;
+        e.key
+    })
+}
+
+ + + +
+ + + +## Function `values` + +Return all values in the map. This requires values to be copyable. + + +
public fun values<K, V: copy>(self: &ordered_map::OrderedMap<K, V>): vector<V>
+
+ + + +
+Implementation + + +
public fun values<K, V: copy>(self: &OrderedMap<K, V>): vector<V> {
+    vector::map_ref(&self.entries, |e| {
+        let e: &Entry<K, V> = e;
+        e.value
+    })
+}
+
+ + + +
+ + + +## Function `to_vec_pair` + +Transform the map into two vectors with the keys and values respectively +Primarily used to destroy a map + + +
public fun to_vec_pair<K, V>(self: ordered_map::OrderedMap<K, V>): (vector<K>, vector<V>)
+
+ + + +
+Implementation + + +
public fun to_vec_pair<K, V>(self: OrderedMap<K, V>): (vector<K>, vector<V>) {
+    let keys: vector<K> = vector::empty();
+    let values: vector<V> = vector::empty();
+    let OrderedMap::SortedVectorMap { entries } = self;
+    vector::for_each(entries, |e| {
+        let Entry { key, value } = e;
+        vector::push_back(&mut keys, key);
+        vector::push_back(&mut values, value);
+    });
+    (keys, values)
+}
+
+ + + +
+ + + +## Function `destroy` + +For maps that cannot be dropped this is a utility to destroy them +using lambdas to destroy the individual keys and values. + + +
public fun destroy<K, V>(self: ordered_map::OrderedMap<K, V>, dk: |K|, dv: |V|)
+
+ + + +
+Implementation + + +
public inline fun destroy<K, V>(
+    self: OrderedMap<K, V>,
+    dk: |K|,
+    dv: |V|
+) {
+    let (keys, values) = to_vec_pair(self);
+    vector::destroy(keys, |_k| dk(_k));
+    vector::destroy(values, |_v| dv(_v));
+}
+
+ + +
@@ -1028,7 +1286,7 @@ Apply the function to a reference of each key-value pair in the table.
public inline fun for_each_ref<K, V>(self: &OrderedMap<K, V>, f: |&K, &V|) {
     let iter = self.new_begin_iter();
-    while (!iter.iter_is_end()) {
+    while (!iter.iter_is_end(self)) {
         f(iter.iter_borrow_key(self), iter.iter_borrow(self));
         iter = iter.iter_next(self);
     }
@@ -1063,7 +1321,7 @@ Apply the function to a mutable reference of each key-value pair in the table.
 
 
public inline fun for_each_mut<K, V>(self: &mut OrderedMap<K, V>, f: |K, &mut V|) {
     let iter = self.new_begin_iter();
-    while (!iter.iter_is_end()) {
+    while (!iter.iter_is_end(self)) {
         let key = *iter.iter_borrow_key(self);
         f(key, iter.iter_borrow_mut(self));
         iter = iter.iter_next(self);
@@ -1127,13 +1385,13 @@ Apply the function to a mutable reference of each key-value pair in the table.
     let r = end;
     while (l != r) {
         let mid = l + (r - l) / 2;
-        let comparison = cmp::compare(&entries.borrow(mid).key, key);
+        let comparison = cmp::compare(&entries.borrow(mid).key, key);
         // TODO: check why this short-circuiting actually performs worse
         // if (comparison.is_equal()) {
         //     // there can only be one equal value, so end the search.
         //     return mid;
         // } else
-        if (comparison.is_less_than()) {
+        if (comparison.is_lt()) {
             l = mid + 1;
         } else {
             r = mid;
diff --git a/aptos-move/framework/aptos-stdlib/sources/data_structures/ordered_map.move b/aptos-move/framework/aptos-stdlib/sources/data_structures/ordered_map.move
index a5df4fc9f7f98..960548c6f0320 100644
--- a/aptos-move/framework/aptos-stdlib/sources/data_structures/ordered_map.move
+++ b/aptos-move/framework/aptos-stdlib/sources/data_structures/ordered_map.move
@@ -68,6 +68,14 @@ module aptos_std::ordered_map {
         }
     }
 
+    /// Create a OrderedMap from a vector of keys and values.
+    /// Aborts with EKEY_ALREADY_EXISTS if duplicate keys are passed in.
+    public fun new_from(keys: vector, values: vector): OrderedMap {
+        let map = new();
+        add_all(&mut map, keys, values);
+        map
+    }
+
     /// Number of elements in the map.
     public fun length(self: &OrderedMap): u64 {
         self.entries.length()
@@ -120,7 +128,15 @@ module aptos_std::ordered_map {
 
     /// Returns whether map contains a given key.
     public fun contains(self: &OrderedMap, key: &K): bool {
-        !self.find(key).iter_is_end()
+        !self.find(key).iter_is_end(self)
+    }
+
+    public fun borrow(self: &OrderedMap, key: &K): &V {
+        self.find(key).iter_borrow(self)
+    }
+
+    public fun borrow_mut(self: &mut OrderedMap, key: &K): &mut V {
+        self.find(key).iter_borrow_mut(self)
     }
 
     /// Changes the key, with keeping the same value attached to it
@@ -132,11 +148,11 @@ module aptos_std::ordered_map {
         assert!(index < len, error::invalid_argument(EKEY_NOT_FOUND));
 
         if (index > 0) {
-            assert!(cmp::compare(&self.entries[index - 1].key, &new_key).is_less_than(), error::invalid_argument(ENEW_KEY_NOT_IN_ORDER))
+            assert!(cmp::compare(&self.entries[index - 1].key, &new_key).is_lt(), error::invalid_argument(ENEW_KEY_NOT_IN_ORDER))
         };
 
         if (index + 1 < len) {
-            assert!(cmp::compare(&new_key, &self.entries[index + 1].key).is_less_than(), error::invalid_argument(ENEW_KEY_NOT_IN_ORDER))
+            assert!(cmp::compare(&new_key, &self.entries[index + 1].key).is_lt(), error::invalid_argument(ENEW_KEY_NOT_IN_ORDER))
         };
 
         let entry = self.entries.borrow_mut(index);
@@ -144,7 +160,16 @@ module aptos_std::ordered_map {
         entry.key = new_key;
     }
 
+    /// Add multiple key/value pairs to the map. The keys must not already exist.
+    /// Aborts with EKEY_ALREADY_EXISTS if key already exist, or duplicate keys are passed in.
+    public fun add_all(self: &mut OrderedMap, keys: vector, values: vector) {
+        vector::zip(keys, values, |key, value| {
+            add(self, key, value);
+        });
+    }
+
     /// Takes all elements from `other` and adds them to `self`.
+    /// Aborts with EKEY_ALREADY_EXISTS if `other` has a key already present in `self`.
     public fun append(self: &mut OrderedMap, other: OrderedMap) {
         let OrderedMap::SortedVectorMap {
             entries: other_entries,
@@ -161,26 +186,49 @@ module aptos_std::ordered_map {
         };
 
         // Optimization: if all elements in `other` are larger than all elements in `self`, we can just move them over.
-        if (cmp::compare(&self.entries.borrow(self.entries.length() - 1).key, &other_entries.borrow(0).key).is_less_than()) {
+        if (cmp::compare(&self.entries.borrow(self.entries.length() - 1).key, &other_entries.borrow(0).key).is_lt()) {
             self.entries.append(other_entries);
             return;
         };
 
-        // TODO: can be implemented more efficiently, as we know both maps are already sorted.
-        while (!other_entries.is_empty()) {
-            let Entry { key, value } = other_entries.pop_back();
-            self.add(key, value);
+        // In O(n), traversing from the back, build reverse sorted result, and then reverse it back
+        let reverse_result = vector::empty();
+        let cur_i = self.entries.length() - 1;
+        let other_i = other_entries.length() - 1;
+
+        // after the end of the loop, entries is empty, and any leftover is in other_entries
+        loop {
+            let ord = cmp::compare(&self.entries[cur_i].key, &other_entries[other_i].key);
+            assert!(!ord.is_eq(), error::invalid_argument(EKEY_ALREADY_EXISTS));
+            if (ord.is_gt()) {
+                reverse_result.push_back(self.entries.pop_back());
+                if (cur_i == 0) {
+                    break;
+                } else {
+                    cur_i = cur_i - 1;
+                }
+            } else {
+                reverse_result.push_back(other_entries.pop_back());
+                if (other_i == 0) {
+                    // make entries empty, and rest in other_entries.
+                    mem::swap(&mut other_entries, &mut self.entries);
+                    break;
+                } else {
+                    other_i = other_i - 1;
+                }
+            };
         };
 
-        other_entries.destroy_empty();
+        reverse_result.reverse_append(other_entries);
+        self.entries.reverse_append(reverse_result);
     }
 
     /// Splits the collection into two, such to leave `self` with `at` number of elements.
     /// Returns a newly allocated map containing the elements in the range [at, len).
     /// After the call, the original map will be left containing the elements [0, at)
     /// with its previous capacity unchanged.
-    public fun split_off(self: &mut OrderedMap, at: u64): OrderedMap {
-        let rest = self.entries.split_off(at);
+    public fun trim(self: &mut OrderedMap, at: u64): OrderedMap {
+        let rest = self.entries.trim(at);
 
         OrderedMap::SortedVectorMap {
             entries: rest
@@ -205,7 +253,7 @@ module aptos_std::ordered_map {
     /// iterator if the key is not found.
     public fun find(self: &OrderedMap, key: &K): Iterator {
         let lower_bound = self.lower_bound(key);
-        if (lower_bound.iter_is_end()) {
+        if (lower_bound.iter_is_end(self)) {
             lower_bound
         } else if (lower_bound.iter_borrow_key(self) == key) {
             lower_bound
@@ -238,7 +286,7 @@ module aptos_std::ordered_map {
     /// Returns the next iterator, or none if already at the end iterator.
     /// Note: Requires that the map is not changed after the input iterator is generated.
     public fun iter_next(self: Iterator, map: &OrderedMap): Iterator {
-        assert!(!self.iter_is_end(), error::invalid_argument(EITER_OUT_OF_BOUNDS));
+        assert!(!self.iter_is_end(map), error::invalid_argument(EITER_OUT_OF_BOUNDS));
 
         let index = self.index + 1;
         if (index < map.entries.length()) {
@@ -283,7 +331,7 @@ module aptos_std::ordered_map {
     }
 
     /// Returns whether the iterator is an end iterator.
-    public fun iter_is_end(self: &Iterator): bool {
+    public fun iter_is_end(self: &Iterator, _map: &OrderedMap): bool {
         self is Iterator::End
     }
 
@@ -337,12 +385,54 @@ module aptos_std::ordered_map {
         entries.destroy_empty();
     }
 
-    // ========= Section with inline for-loop methods =======
+    // ========= Section with views and inline for-loop methods =======
+
+    /// Return all keys in the map. This requires keys to be copyable.
+    public fun keys(self: &OrderedMap): vector {
+        vector::map_ref(&self.entries, |e| {
+            let e: &Entry = e;
+            e.key
+        })
+    }
+
+    /// Return all values in the map. This requires values to be copyable.
+    public fun values(self: &OrderedMap): vector {
+        vector::map_ref(&self.entries, |e| {
+            let e: &Entry = e;
+            e.value
+        })
+    }
+
+    /// Transform the map into two vectors with the keys and values respectively
+    /// Primarily used to destroy a map
+    public fun to_vec_pair(self: OrderedMap): (vector, vector) {
+        let keys: vector = vector::empty();
+        let values: vector = vector::empty();
+        let OrderedMap::SortedVectorMap { entries } = self;
+        vector::for_each(entries, |e| {
+            let Entry { key, value } = e;
+            vector::push_back(&mut keys, key);
+            vector::push_back(&mut values, value);
+        });
+        (keys, values)
+    }
+
+    /// For maps that cannot be dropped this is a utility to destroy them
+    /// using lambdas to destroy the individual keys and values.
+    public inline fun destroy(
+        self: OrderedMap,
+        dk: |K|,
+        dv: |V|
+    ) {
+        let (keys, values) = to_vec_pair(self);
+        vector::destroy(keys, |_k| dk(_k));
+        vector::destroy(values, |_v| dv(_v));
+    }
 
     /// Apply the function to a reference of each key-value pair in the table.
     public inline fun for_each_ref(self: &OrderedMap, f: |&K, &V|) {
         let iter = self.new_begin_iter();
-        while (!iter.iter_is_end()) {
+        while (!iter.iter_is_end(self)) {
             f(iter.iter_borrow_key(self), iter.iter_borrow(self));
             iter = iter.iter_next(self);
         }
@@ -357,7 +447,7 @@ module aptos_std::ordered_map {
     /// Apply the function to a mutable reference of each key-value pair in the table.
     public inline fun for_each_mut(self: &mut OrderedMap, f: |K, &mut V|) {
         let iter = self.new_begin_iter();
-        while (!iter.iter_is_end()) {
+        while (!iter.iter_is_end(self)) {
             let key = *iter.iter_borrow_key(self);
             f(key, iter.iter_borrow_mut(self));
             iter = iter.iter_next(self);
@@ -391,7 +481,7 @@ module aptos_std::ordered_map {
             //     // there can only be one equal value, so end the search.
             //     return mid;
             // } else
-            if (comparison.is_less_than()) {
+            if (comparison.is_lt()) {
                 l = mid + 1;
             } else {
                 r = mid;
@@ -420,7 +510,7 @@ module aptos_std::ordered_map {
         let len = self.entries.length();
         let i = 1;
         while (i < len) {
-            assert!(cmp::compare(&self.entries.borrow(i).key, &self.entries.borrow(i - 1).key).is_greater_than(), 1);
+            assert!(cmp::compare(&self.entries.borrow(i).key, &self.entries.borrow(i - 1).key).is_gt(), 1);
             i = i + 1;
         };
     }
@@ -430,7 +520,7 @@ module aptos_std::ordered_map {
         let expected_num_elements = self.length();
         let num_elements = 0;
         let it = self.new_begin_iter();
-        while (!it.iter_is_end()) {
+        while (!it.iter_is_end(self)) {
             num_elements = num_elements + 1;
             it = it.iter_next(self);
         };
@@ -475,6 +565,170 @@ module aptos_std::ordered_map {
         map.destroy_empty();
     }
 
+    #[test]
+    public fun test_add_remove_many() {
+        let map = new();
+
+        assert!(length(&map) == 0, 0);
+        assert!(!contains(&map, &3), 1);
+        add(&mut map, 3, 1);
+        assert!(length(&map) == 1, 2);
+        assert!(contains(&map, &3), 3);
+        assert!(borrow(&map, &3) == &1, 4);
+        *borrow_mut(&mut map, &3) = 2;
+        assert!(borrow(&map, &3) == &2, 5);
+
+        assert!(!contains(&map, &2), 6);
+        add(&mut map, 2, 5);
+        assert!(length(&map) == 2, 7);
+        assert!(contains(&map, &2), 8);
+        assert!(borrow(&map, &2) == &5, 9);
+        *borrow_mut(&mut map, &2) = 9;
+        assert!(borrow(&map, &2) == &9, 10);
+
+        remove(&mut map, &2);
+        assert!(length(&map) == 1, 11);
+        assert!(!contains(&map, &2), 12);
+        assert!(borrow(&map, &3) == &2, 13);
+
+        remove(&mut map, &3);
+        assert!(length(&map) == 0, 14);
+        assert!(!contains(&map, &3), 15);
+
+        destroy_empty(map);
+    }
+
+    #[test]
+    public fun test_add_all() {
+        let map = new();
+
+        assert!(length(&map) == 0, 0);
+        add_all(&mut map, vector[1, 2, 3], vector[10, 20, 30]);
+        assert!(length(&map) == 3, 1);
+        assert!(borrow(&map, &1) == &10, 2);
+        assert!(borrow(&map, &2) == &20, 3);
+        assert!(borrow(&map, &3) == &30, 4);
+
+        remove(&mut map, &1);
+        remove(&mut map, &2);
+        remove(&mut map, &3);
+        destroy_empty(map);
+    }
+
+    #[test]
+    public fun test_keys() {
+        let map = new();
+        assert!(keys(&map) == vector[], 0);
+        add(&mut map, 2, 1);
+        add(&mut map, 3, 1);
+
+        assert!(keys(&map) == vector[2, 3], 0);
+    }
+
+    #[test]
+    public fun test_values() {
+        let map = new();
+        assert!(values(&map) == vector[], 0);
+        add(&mut map, 2, 1);
+        add(&mut map, 3, 2);
+
+        assert!(values(&map) == vector[1, 2], 0);
+    }
+
+    #[test]
+    #[expected_failure]
+    public fun test_add_twice() {
+        let map = new();
+        add(&mut map, 3, 1);
+        add(&mut map, 3, 1);
+
+        remove(&mut map, &3);
+        destroy_empty(map);
+    }
+
+    #[test]
+    #[expected_failure]
+    public fun test_remove_twice() {
+        let map = new();
+        add(&mut map, 3, 1);
+        remove(&mut map, &3);
+        remove(&mut map, &3);
+
+        destroy_empty(map);
+    }
+
+    #[test]
+    public fun test_upsert_test() {
+        let map = new();
+        // test adding 3 elements using upsert
+        upsert(&mut map, 1, 1);
+        upsert(&mut map, 2, 2);
+        upsert(&mut map, 3, 3);
+
+        assert!(length(&map) == 3, 0);
+        assert!(contains(&map, &1), 1);
+        assert!(contains(&map, &2), 2);
+        assert!(contains(&map, &3), 3);
+        assert!(borrow(&map, &1) == &1, 4);
+        assert!(borrow(&map, &2) == &2, 5);
+        assert!(borrow(&map, &3) == &3, 6);
+
+        // change mapping 1->1 to 1->4
+        upsert(&mut map, 1, 4);
+
+        assert!(length(&map) == 3, 7);
+        assert!(contains(&map, &1), 8);
+        assert!(borrow(&map, &1) == &4, 9);
+    }
+
+    #[test]
+    fun test_append() {
+        {
+            let map = new();
+            let other = new();
+            map.append(other);
+            assert!(map.is_empty(), 0);
+        };
+        {
+            let map = new_from(vector[1, 2], vector[10, 20]);
+            let other = new();
+            map.append(other);
+            assert!(map == new_from(vector[1, 2], vector[10, 20]), 1);
+        };
+        {
+            let map = new();
+            let other = new_from(vector[1, 2], vector[10, 20]);
+            map.append(other);
+            assert!(map == new_from(vector[1, 2], vector[10, 20]), 2);
+        };
+        {
+            let map = new_from(vector[1, 2, 3], vector[10, 20, 30]);
+            let other = new_from(vector[4, 5], vector[40, 50]);
+            map.append(other);
+            assert!(map == new_from(vector[1, 2, 3, 4, 5], vector[10, 20, 30, 40, 50]), 3);
+        };
+        {
+            let map = new_from(vector[1, 3, 5], vector[10, 30, 50]);
+            let other = new_from(vector[2, 4], vector[20, 40]);
+            map.append(other);
+            assert!(map == new_from(vector[1, 2, 3, 4, 5], vector[10, 20, 30, 40, 50]), 3);
+        };
+        {
+            let map = new_from(vector[2, 4], vector[20, 40]);
+            let other = new_from(vector[1, 3, 5], vector[10, 30, 50]);
+            map.append(other);
+            assert!(map == new_from(vector[1, 2, 3, 4, 5], vector[10, 20, 30, 40, 50]), 3);
+        };
+    }
+
+    #[test]
+    #[expected_failure(abort_code = 0x10001 )] /// EKEY_ALREADY_EXISTS
+    fun test_append_abort() {
+        let map = new_from(vector[1], vector[10]);
+        let other = new_from(vector[1], vector[10]);
+        map.append(other);
+    }
+
     #[test_only]
     public fun large_dataset(): vector {
         vector[383, 886, 777, 915, 793, 335, 386, 492, 649, 421, 362, 27, 690, 59, 763, 926, 540, 426, 172, 736, 211, 368, 567, 429, 782, 530, 862, 123, 67, 135, 929, 802, 22, 58, 69, 167, 393, 456, 11, 42, 229, 373, 421, 919, 784, 537, 198, 324, 315, 370, 413, 526, 91, 980, 956, 873, 862, 170, 996, 281, 305, 925, 84, 327, 336, 505, 846, 729, 313, 857, 124, 895, 582, 545, 814, 367, 434, 364, 43, 750, 87, 808, 276, 178, 788, 584, 403, 651, 754, 399, 932, 60, 676, 368, 739, 12, 226, 586, 94, 539, 795, 570, 434, 378, 467, 601, 97, 902, 317, 492, 652, 756, 301, 280, 286, 441, 865, 689, 444, 619, 440, 729, 31, 117, 97, 771, 481, 675, 709, 927, 567, 856, 497, 353, 586, 965, 306, 683, 219, 624, 528, 871, 732, 829, 503, 19, 270, 368, 708, 715, 340, 149, 796, 723, 618, 245, 846, 451, 921, 555, 379, 488, 764, 228, 841, 350, 193, 500, 34, 764, 124, 914, 987, 856, 743, 491, 227, 365, 859, 936, 432, 551, 437, 228, 275, 407, 474, 121, 858, 395, 29, 237, 235, 793, 818, 428, 143, 11, 928, 529]
@@ -487,8 +741,6 @@ module aptos_std::ordered_map {
 
     #[test]
     fun test_map_large() {
-        use std::string;
-
         let map = new();
         let data = large_dataset();
         let shuffled_data = large_dataset_shuffled();
@@ -503,7 +755,7 @@ module aptos_std::ordered_map {
         for (i in 0..len) {
             let element = shuffled_data.borrow(i);
             let it = map.find(element);
-            assert!(!it.iter_is_end(), 6);
+            assert!(!it.iter_is_end(&map), 6);
             assert!(it.iter_borrow_key(&map) == element, 7);
 
             let it_next = it.iter_next(&map);
diff --git a/aptos-move/framework/move-stdlib/doc/cmp.md b/aptos-move/framework/move-stdlib/doc/cmp.md
index 266916e9115f2..18c5363cd9723 100644
--- a/aptos-move/framework/move-stdlib/doc/cmp.md
+++ b/aptos-move/framework/move-stdlib/doc/cmp.md
@@ -95,7 +95,7 @@ and if equal we proceed to the next.
 - enum's are compared first by their variant, and if equal - they are compared as structs are.
 
 
-
public(friend) fun compare<T>(first: &T, second: &T): cmp::Ordering
+
public fun compare<T>(first: &T, second: &T): cmp::Ordering
 
@@ -104,7 +104,7 @@ and if equal we proceed to the next. Implementation -
native public(friend) fun compare<T>(first: &T, second: &T): Ordering;
+
native public fun compare<T>(first: &T, second: &T): Ordering;
 
diff --git a/aptos-move/framework/move-stdlib/doc/mem.md b/aptos-move/framework/move-stdlib/doc/mem.md index b4ac9b3f608be..29af5657e4049 100644 --- a/aptos-move/framework/move-stdlib/doc/mem.md +++ b/aptos-move/framework/move-stdlib/doc/mem.md @@ -27,7 +27,7 @@ Move prevents from having two mutable references to the same value, so left and right references are always distinct. -
public(friend) fun swap<T>(left: &mut T, right: &mut T)
+
public fun swap<T>(left: &mut T, right: &mut T)
 
@@ -36,7 +36,7 @@ so left and right references are always distinct. Implementation -
public(friend) native fun swap<T>(left: &mut T, right: &mut T);
+
public native fun swap<T>(left: &mut T, right: &mut T);
 
@@ -51,7 +51,7 @@ Replace the value reference points to with the given new value, and return the value it had before. -
public(friend) fun replace<T>(ref: &mut T, new: T): T
+
public fun replace<T>(ref: &mut T, new: T): T
 
@@ -60,7 +60,7 @@ and return the value it had before. Implementation -
public(friend) fun replace<T>(ref: &mut T, new: T): T {
+
public fun replace<T>(ref: &mut T, new: T): T {
     swap(ref, &mut new);
     new
 }
@@ -80,7 +80,7 @@ and return the value it had before.
 ### Function `swap`
 
 
-
public(friend) fun swap<T>(left: &mut T, right: &mut T)
+
public fun swap<T>(left: &mut T, right: &mut T)
 
@@ -99,7 +99,7 @@ and return the value it had before. ### Function `replace` -
public(friend) fun replace<T>(ref: &mut T, new: T): T
+
public fun replace<T>(ref: &mut T, new: T): T
 
diff --git a/aptos-move/framework/move-stdlib/sources/cmp.move b/aptos-move/framework/move-stdlib/sources/cmp.move index fcb56573e0e51..9ab6b05755f51 100644 --- a/aptos-move/framework/move-stdlib/sources/cmp.move +++ b/aptos-move/framework/move-stdlib/sources/cmp.move @@ -8,18 +8,13 @@ module std::cmp { Greater, } - // TODO - functions here are `public(friend)` here for one release, - // and to be changed to `public` one release later. - #[test_only] - friend std::bcs_tests; - /// Compares two values with the natural ordering: /// - native types are compared identically to `<` and other operators /// - complex types /// - Structs and vectors - are compared lexicographically - first field/element is compared first, /// and if equal we proceed to the next. /// - enum's are compared first by their variant, and if equal - they are compared as structs are. - native public(friend) fun compare(first: &T, second: &T): Ordering; + native public fun compare(first: &T, second: &T): Ordering; public fun is_eq(self: &Ordering): bool { self is Ordering::Equal diff --git a/aptos-move/framework/move-stdlib/sources/mem.move b/aptos-move/framework/move-stdlib/sources/mem.move index e96db063db6c0..0f545b5116915 100644 --- a/aptos-move/framework/move-stdlib/sources/mem.move +++ b/aptos-move/framework/move-stdlib/sources/mem.move @@ -1,20 +1,14 @@ /// Module with methods for safe memory manipulation. module std::mem { - // TODO - functions here are `public(friend)` here for one release, - // and to be changed to `public` one release later. - friend std::vector; - #[test_only] - friend std::mem_tests; - /// Swap contents of two passed mutable references. /// /// Move prevents from having two mutable references to the same value, /// so `left` and `right` references are always distinct. - public(friend) native fun swap(left: &mut T, right: &mut T); + public native fun swap(left: &mut T, right: &mut T); /// Replace the value reference points to with the given new value, /// and return the value it had before. - public(friend) fun replace(ref: &mut T, new: T): T { + public fun replace(ref: &mut T, new: T): T { swap(ref, &mut new); new } diff --git a/crates/transaction-generator-lib/src/publishing/module_simple.rs b/crates/transaction-generator-lib/src/publishing/module_simple.rs index 18ecea402c8ef..bcc59dfa6866d 100644 --- a/crates/transaction-generator-lib/src/publishing/module_simple.rs +++ b/crates/transaction-generator-lib/src/publishing/module_simple.rs @@ -624,15 +624,11 @@ impl EntryPoints { len, repeats, use_simple_map, - } => get_payload( - module_id, - ident_str!("test_split_off_append").to_owned(), - vec![ - bcs::to_bytes(len).unwrap(), - bcs::to_bytes(repeats).unwrap(), - bcs::to_bytes(use_simple_map).unwrap(), - ], - ), + } => get_payload(module_id, ident_str!("test_add_remove").to_owned(), vec![ + bcs::to_bytes(len).unwrap(), + bcs::to_bytes(repeats).unwrap(), + bcs::to_bytes(use_simple_map).unwrap(), + ]), EntryPoints::TokenV1InitializeCollection => get_payload_void( module_id, ident_str!("token_v1_initialize_collection").to_owned(), diff --git a/crates/transaction-generator-lib/src/publishing/raw_module_data.rs b/crates/transaction-generator-lib/src/publishing/raw_module_data.rs index 7bc806e4c36b0..c0d43ee052b03 100644 --- a/crates/transaction-generator-lib/src/publishing/raw_module_data.rs +++ b/crates/transaction-generator-lib/src/publishing/raw_module_data.rs @@ -764,12 +764,12 @@ pub static PACKAGE_SIMPLE_METADATA: Lazy> = Lazy::new(|| { #[rustfmt::skip] pub static SCRIPT_SIMPLE: Lazy> = Lazy::new(|| { - vec![ - 161, 28, 235, 11, 7, 0, 0, 10, 2, 5, 0, 4, 6, 4, 34, 1, 6, 12, - 0, 5, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, - 0, 1, 3, 11, 0, 1, 2, - ] + vec![ + 161, 28, 235, 11, 7, 0, 0, 10, 2, 5, 0, 4, 6, 4, 34, 1, 6, 12, + 0, 5, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 1, 3, 11, 0, 1, 2, + ] }); #[rustfmt::skip] @@ -984,11 +984,11 @@ pub static MODULES_SIMPLE: Lazy>> = Lazy::new(|| { vec![ pub static PACKAGE_FRAMEWORK_USECASES_METADATA: Lazy> = Lazy::new(|| { vec![ 17, 70, 114, 97, 109, 101, 119, 111, 114, 107, 85, 115, 101, 99, 97, 115, 101, 115, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 64, 66, 67, 69, 48, 54, 67, 49, 52, - 57, 67, 52, 51, 66, 56, 50, 53, 55, 53, 48, 54, 67, 65, 65, 57, 66, 66, - 70, 65, 51, 52, 51, 66, 69, 55, 56, 57, 57, 55, 67, 50, 56, 52, 70, 53, - 49, 56, 67, 70, 65, 55, 66, 57, 49, 54, 67, 50, 53, 69, 55, 56, 68, 55, - 55, 69, 215, 1, 31, 139, 8, 0, 0, 0, 0, 0, 2, 255, 165, 144, 187, 142, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 64, 68, 65, 68, 69, 51, 69, 49, 70, + 54, 54, 52, 70, 65, 54, 67, 69, 66, 52, 68, 68, 48, 49, 67, 65, 53, 50, + 55, 68, 70, 51, 50, 55, 70, 51, 52, 51, 68, 49, 50, 48, 68, 66, 51, 49, + 51, 53, 56, 69, 57, 67, 68, 54, 57, 55, 51, 57, 57, 57, 50, 51, 57, 57, + 51, 70, 215, 1, 31, 139, 8, 0, 0, 0, 0, 0, 2, 255, 165, 144, 187, 142, 194, 64, 12, 69, 251, 249, 10, 107, 182, 38, 236, 15, 108, 193, 238, 138, 150, 6, 170, 8, 33, 51, 49, 33, 100, 176, 163, 241, 240, 144, 16, 255, 78, 44, 30, 130, 22, 100, 23, 215, 246, 189, 167, 112, 217, 97, 104, 177, 166, 185, 99, 220, 18, 252, @@ -1000,27 +1000,28 @@ pub static PACKAGE_FRAMEWORK_USECASES_METADATA: Lazy> = Lazy::new(|| { 134, 107, 160, 99, 88, 35, 215, 38, 101, 5, 65, 88, 51, 114, 6, 172, 170, 68, 170, 96, 20, 5, 236, 5, 197, 88, 184, 242, 182, 183, 231, 117, 187, 101, 108, 116, 77, 105, 113, 55, 219, 163, 143, 163, 223, 191, 127, 239, 46, 112, 10, 188, 112, 161, - 1, 0, 0, 7, 18, 97, 103, 103, 114, 101, 103, 97, 116, 111, 114, 95, 101, 120, + 1, 0, 0, 8, 18, 97, 103, 103, 114, 101, 103, 97, 116, 111, 114, 95, 101, 120, 97, 109, 112, 108, 101, 0, 0, 0, 12, 99, 111, 105, 110, 95, 101, 120, 97, 109, 112, 108, 101, 0, 0, 0, 22, 102, 117, 110, 103, 105, 98, 108, 101, 95, 97, 115, - 115, 101, 116, 95, 101, 120, 97, 109, 112, 108, 101, 0, 0, 0, 7, 111, 98, 106, - 101, 99, 116, 115, 0, 0, 0, 23, 114, 101, 115, 111, 117, 114, 99, 101, 95, 103, - 114, 111, 117, 112, 115, 95, 101, 120, 97, 109, 112, 108, 101, 0, 0, 0, 8, 116, - 111, 107, 101, 110, 95, 118, 49, 0, 0, 0, 14, 118, 101, 99, 116, 111, 114, 95, - 101, 120, 97, 109, 112, 108, 101, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, + 115, 101, 116, 95, 101, 120, 97, 109, 112, 108, 101, 0, 0, 0, 12, 109, 97, 112, + 115, 95, 101, 120, 97, 109, 112, 108, 101, 0, 0, 0, 7, 111, 98, 106, 101, 99, + 116, 115, 0, 0, 0, 23, 114, 101, 115, 111, 117, 114, 99, 101, 95, 103, 114, 111, + 117, 112, 115, 95, 101, 120, 97, 109, 112, 108, 101, 0, 0, 0, 8, 116, 111, 107, + 101, 110, 95, 118, 49, 0, 0, 0, 14, 118, 101, 99, 116, 111, 114, 95, 101, 120, + 97, 109, 112, 108, 101, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 14, 65, 112, 116, 111, 115, 70, 114, 97, 109, 101, - 119, 111, 114, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - 11, 65, 112, 116, 111, 115, 83, 116, 100, 108, 105, 98, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 14, 65, 112, 116, 111, 115, 70, 114, 97, 109, 101, 119, 111, + 114, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 11, 65, + 112, 116, 111, 115, 83, 116, 100, 108, 105, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 10, 77, 111, 118, 101, 83, 116, 100, 108, 105, - 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 10, 65, 112, - 116, 111, 115, 84, 111, 107, 101, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 10, 77, 111, 118, 101, 83, 116, 100, 108, 105, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 4, 17, 65, 112, 116, 111, 115, 84, 111, 107, 101, 110, 79, 98, 106, - 101, 99, 116, 115, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 10, 65, 112, 116, 111, + 115, 84, 111, 107, 101, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4, 17, 65, 112, 116, 111, 115, 84, 111, 107, 101, 110, 79, 98, 106, 101, 99, + 116, 115, 0, ] }); @@ -1223,6 +1224,54 @@ pub static MODULE_FRAMEWORK_USECASES_FUNGIBLE_ASSET_EXAMPLE: Lazy> = Laz ] }); +#[rustfmt::skip] +pub static MODULE_FRAMEWORK_USECASES_MAPS_EXAMPLE: Lazy> = Lazy::new(|| { + vec![ + 161, 28, 235, 11, 7, 0, 0, 10, 9, 1, 0, 6, 2, 6, 16, 3, 22, 54, + 4, 76, 12, 5, 88, 102, 7, 190, 1, 88, 8, 150, 2, 64, 16, 214, 2, 31, + 12, 245, 2, 208, 2, 0, 0, 1, 2, 1, 5, 1, 4, 7, 2, 0, 0, 0, + 0, 2, 6, 7, 2, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 3, 1, + 3, 2, 4, 4, 1, 2, 3, 1, 4, 2, 0, 0, 1, 1, 7, 5, 1, 2, + 4, 4, 1, 2, 7, 6, 1, 2, 0, 0, 1, 1, 8, 7, 8, 2, 4, 4, + 1, 2, 8, 9, 10, 2, 2, 0, 1, 1, 2, 2, 2, 3, 2, 4, 2, 5, + 2, 6, 2, 3, 3, 3, 1, 0, 2, 3, 3, 1, 11, 0, 2, 9, 0, 9, + 1, 1, 11, 1, 2, 9, 0, 9, 1, 3, 7, 11, 0, 2, 9, 0, 9, 1, + 9, 0, 9, 1, 3, 7, 11, 1, 2, 9, 0, 9, 1, 9, 0, 9, 1, 2, + 7, 11, 0, 2, 9, 0, 9, 1, 6, 9, 0, 2, 9, 0, 9, 1, 2, 7, + 11, 1, 2, 9, 0, 9, 1, 6, 9, 0, 1, 9, 1, 11, 3, 3, 11, 0, + 2, 3, 3, 11, 1, 2, 3, 3, 3, 1, 3, 1, 3, 3, 3, 12, 109, 97, + 112, 115, 95, 101, 120, 97, 109, 112, 108, 101, 15, 116, 101, 115, 116, 95, 97, 100, + 100, 95, 114, 101, 109, 111, 118, 101, 10, 115, 105, 109, 112, 108, 101, 95, 109, 97, + 112, 3, 110, 101, 119, 9, 83, 105, 109, 112, 108, 101, 77, 97, 112, 11, 111, 114, + 100, 101, 114, 101, 100, 95, 109, 97, 112, 10, 79, 114, 100, 101, 114, 101, 100, 77, + 97, 112, 3, 97, 100, 100, 6, 114, 101, 109, 111, 118, 101, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 171, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 20, 99, 111, 109, 112, 105, 108, 97, 116, 105, 111, 110, 95, + 109, 101, 116, 97, 100, 97, 116, 97, 9, 0, 3, 50, 46, 48, 3, 50, 46, 49, + 0, 1, 4, 0, 11, 123, 6, 210, 4, 0, 0, 0, 0, 0, 0, 12, 3, 6, + 210, 4, 0, 0, 0, 0, 0, 0, 12, 4, 56, 0, 12, 5, 56, 1, 12, 6, + 6, 0, 0, 0, 0, 0, 0, 0, 0, 12, 7, 9, 12, 8, 5, 14, 5, 50, + 10, 8, 4, 120, 11, 7, 6, 1, 0, 0, 0, 0, 0, 0, 0, 22, 12, 7, + 10, 7, 10, 0, 35, 3, 25, 5, 50, 10, 2, 4, 45, 13, 5, 10, 3, 10, + 3, 56, 2, 11, 3, 6, 177, 30, 4, 0, 0, 0, 0, 0, 22, 12, 3, 10, + 3, 6, 64, 66, 15, 0, 0, 0, 0, 0, 36, 3, 40, 5, 12, 11, 3, 6, + 64, 66, 15, 0, 0, 0, 0, 0, 23, 12, 3, 5, 12, 13, 6, 10, 3, 10, + 3, 56, 3, 5, 31, 6, 0, 0, 0, 0, 0, 0, 0, 0, 12, 9, 9, 12, + 10, 11, 1, 12, 11, 5, 58, 5, 116, 10, 10, 4, 117, 11, 9, 6, 1, 0, + 0, 0, 0, 0, 0, 0, 22, 12, 9, 10, 9, 10, 11, 35, 3, 69, 5, 116, + 10, 2, 4, 107, 13, 5, 10, 3, 10, 3, 56, 2, 13, 5, 14, 4, 56, 4, + 1, 1, 11, 3, 6, 177, 30, 4, 0, 0, 0, 0, 0, 22, 12, 3, 10, 3, + 6, 64, 66, 15, 0, 0, 0, 0, 0, 36, 3, 89, 5, 93, 11, 3, 6, 64, + 66, 15, 0, 0, 0, 0, 0, 23, 12, 3, 11, 4, 6, 177, 30, 4, 0, 0, + 0, 0, 0, 22, 12, 4, 10, 4, 6, 64, 66, 15, 0, 0, 0, 0, 0, 36, + 3, 102, 5, 56, 11, 4, 6, 64, 66, 15, 0, 0, 0, 0, 0, 23, 12, 4, + 5, 56, 13, 6, 10, 3, 10, 3, 56, 3, 13, 6, 14, 4, 56, 5, 1, 5, + 80, 2, 8, 12, 10, 5, 64, 8, 12, 8, 5, 20, 0, + ] +}); + #[rustfmt::skip] pub static MODULE_FRAMEWORK_USECASES_OBJECTS: Lazy> = Lazy::new(|| { vec![ @@ -1649,6 +1698,7 @@ pub static MODULES_FRAMEWORK_USECASES: Lazy>> = Lazy::new(|| { vec![ MODULE_FRAMEWORK_USECASES_AGGREGATOR_EXAMPLE.to_vec(), MODULE_FRAMEWORK_USECASES_COIN_EXAMPLE.to_vec(), MODULE_FRAMEWORK_USECASES_FUNGIBLE_ASSET_EXAMPLE.to_vec(), + MODULE_FRAMEWORK_USECASES_MAPS_EXAMPLE.to_vec(), MODULE_FRAMEWORK_USECASES_OBJECTS.to_vec(), MODULE_FRAMEWORK_USECASES_RESOURCE_GROUPS_EXAMPLE.to_vec(), MODULE_FRAMEWORK_USECASES_TOKEN_V1.to_vec(), diff --git a/testsuite/module-publish/src/packages/framework_usecases/sources/maps_example.move b/testsuite/module-publish/src/packages/framework_usecases/sources/maps_example.move index faeae32dc2031..80d603b751093 100644 --- a/testsuite/module-publish/src/packages/framework_usecases/sources/maps_example.move +++ b/testsuite/module-publish/src/packages/framework_usecases/sources/maps_example.move @@ -6,7 +6,7 @@ module 0xABCD::maps_example { const OFFSET: u64 = 270001; const MOD: u64 = 1000000; - public entry fun test_split_off_append(len: u64, repeats: u64, use_simple_map: bool) { + public entry fun test_add_remove(len: u64, repeats: u64, use_simple_map: bool) { // y is same sequence of values as x, just lagging len behind // so that map always has len elements. let x = 1234;