Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add upsert and destroy also to vector #6860

Merged
merged 14 commits into from
Mar 15, 2023
92 changes: 92 additions & 0 deletions aptos-move/framework/aptos-stdlib/doc/simple_map.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ This module provides a solution for sorted maps, that is it has the properties t
- [Function `contains_key`](#0x1_simple_map_contains_key)
- [Function `destroy_empty`](#0x1_simple_map_destroy_empty)
- [Function `add`](#0x1_simple_map_add)
- [Function `to_vec`](#0x1_simple_map_to_vec)
- [Function `split_element`](#0x1_simple_map_split_element)
- [Function `upsert`](#0x1_simple_map_upsert)
- [Function `remove`](#0x1_simple_map_remove)
- [Function `find`](#0x1_simple_map_find)
- [Specification](#@Specification_1)
Expand Down Expand Up @@ -320,6 +323,95 @@ Map key is not found



</details>

<a name="0x1_simple_map_to_vec"></a>

## Function `to_vec`



<pre><code><b>public</b> <b>fun</b> <a href="simple_map.md#0x1_simple_map_to_vec">to_vec</a>&lt;Key: store, Value: store&gt;(map: <a href="simple_map.md#0x1_simple_map_SimpleMap">simple_map::SimpleMap</a>&lt;Key, Value&gt;): <a href="../../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;<a href="simple_map.md#0x1_simple_map_Element">simple_map::Element</a>&lt;Key, Value&gt;&gt;
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="simple_map.md#0x1_simple_map_to_vec">to_vec</a>&lt;Key: store, Value: store&gt;(
map: <a href="simple_map.md#0x1_simple_map_SimpleMap">SimpleMap</a>&lt;Key, Value&gt;): <a href="../../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;<a href="simple_map.md#0x1_simple_map_Element">Element</a>&lt;Key, Value&gt;&gt; {
<b>let</b> <a href="simple_map.md#0x1_simple_map_SimpleMap">SimpleMap</a> { data } = map;
data
}
</code></pre>



</details>

<a name="0x1_simple_map_split_element"></a>

## Function `split_element`



<pre><code><b>public</b> <b>fun</b> <a href="simple_map.md#0x1_simple_map_split_element">split_element</a>&lt;Key: store, Value: store&gt;(e: <a href="simple_map.md#0x1_simple_map_Element">simple_map::Element</a>&lt;Key, Value&gt;): (Key, Value)
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="simple_map.md#0x1_simple_map_split_element">split_element</a>&lt;Key: store, Value: store&gt;(e: <a href="simple_map.md#0x1_simple_map_Element">Element</a>&lt;Key, Value&gt;): (Key, Value) {
<b>let</b> <a href="simple_map.md#0x1_simple_map_Element">Element</a> { key, value} = e;
(key, value)
}
</code></pre>



</details>

<a name="0x1_simple_map_upsert"></a>

## Function `upsert`



<pre><code><b>public</b> <b>fun</b> <a href="simple_map.md#0x1_simple_map_upsert">upsert</a>&lt;Key: <b>copy</b>, drop, store, Value: <b>copy</b>, drop, store&gt;(map: &<b>mut</b> <a href="simple_map.md#0x1_simple_map_SimpleMap">simple_map::SimpleMap</a>&lt;Key, Value&gt;, key: &Key, value: &Value)
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="simple_map.md#0x1_simple_map_upsert">upsert</a>&lt;Key: store + drop + <b>copy</b>, Value: store + drop + <b>copy</b>&gt;(
map: &<b>mut</b> <a href="simple_map.md#0x1_simple_map_SimpleMap">SimpleMap</a>&lt;Key, Value&gt;,
key: &Key,
value: &Value
) {
<b>let</b> len = std::vector::length(&map.data);
<b>let</b> i = 0;
<b>while</b> (i &lt; len) {
<b>let</b> element = <a href="../../move-stdlib/doc/vector.md#0x1_vector_borrow_mut">vector::borrow_mut</a>(&<b>mut</b> map.data, i);
<b>if</b> (&element.key == key) {
element.value = *value;
<b>return</b>
};
i = i + 1;
};
<a href="../../move-stdlib/doc/vector.md#0x1_vector_push_back">vector::push_back</a>(&<b>mut</b> map.data, <a href="simple_map.md#0x1_simple_map_Element">Element</a> { key: *key, value: *value });
}
</code></pre>



</details>

<a name="0x1_simple_map_remove"></a>
Expand Down
53 changes: 53 additions & 0 deletions aptos-move/framework/aptos-stdlib/sources/simple_map.move
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,35 @@ module aptos_std::simple_map {
vector::push_back(&mut map.data, Element { key, value });
}

public fun to_vec<Key: store, Value: store>(
map: SimpleMap<Key, Value>): vector<Element<Key, Value>> {
let SimpleMap { data } = map;
data
}

public fun split_element<Key: store, Value: store>(e: Element<Key, Value>): (Key, Value) {
let Element { key, value} = e;
(key, value)
}

public fun upsert<Key: store + drop + copy, Value: store + drop + copy>(
map: &mut SimpleMap<Key, Value>,
key: &Key,
value: &Value
) {
let len = std::vector::length(&map.data);
let i = 0;
while (i < len) {
let element = vector::borrow_mut(&mut map.data, i);
if (&element.key == key) {
element.value = *value;
return
};
i = i + 1;
};
vector::push_back(&mut map.data, Element { key: *key, value: *value });
}

public fun remove<Key: store, Value: store>(
map: &mut SimpleMap<Key, Value>,
key: &Key,
Expand Down Expand Up @@ -158,4 +187,28 @@ module aptos_std::simple_map {

destroy_empty(map);
}

#[test]
public fun upsert_test() {
let map = create<u64, u64>();
// test adding 3 elements using upsert
upsert<u64, u64>(&mut map, &1, &1 );
upsert(&mut map, &2, &2 );
upsert(&mut map, &3, &3 );

assert!(length(&map) == 3, 0);
assert!(contains_key(&map, &1), 1);
assert!(contains_key(&map, &2), 2);
assert!(contains_key(&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_key(&map, &1), 8);
assert!(borrow(&map, &1) == &4, 9);
}
}