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

Change big_ordered_map::Node to enum for easier maintanability #15787

Merged
merged 2 commits into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
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
66 changes: 53 additions & 13 deletions aptos-move/framework/aptos-framework/doc/big_ordered_map.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ They are waiting for Move improvement that will allow references to be part of t
allowing cleaner iterator APIs.


- [Struct `Node`](#0x1_big_ordered_map_Node)
- [Enum `Node`](#0x1_big_ordered_map_Node)
- [Enum `Child`](#0x1_big_ordered_map_Child)
- [Enum `IteratorPtr`](#0x1_big_ordered_map_IteratorPtr)
- [Enum `BigOrderedMap`](#0x1_big_ordered_map_BigOrderedMap)
Expand All @@ -35,6 +35,7 @@ allowing cleaner iterator APIs.
- [Function `new_with_config`](#0x1_big_ordered_map_new_with_config)
- [Function `new_from`](#0x1_big_ordered_map_new_from)
- [Function `destroy_empty`](#0x1_big_ordered_map_destroy_empty)
- [Function `allocate_spare_slots`](#0x1_big_ordered_map_allocate_spare_slots)
- [Function `add`](#0x1_big_ordered_map_add)
- [Function `upsert`](#0x1_big_ordered_map_upsert)
- [Function `remove`](#0x1_big_ordered_map_remove)
Expand Down Expand Up @@ -99,7 +100,7 @@ allowing cleaner iterator APIs.

<a id="0x1_big_ordered_map_Node"></a>

## Struct `Node`
## Enum `Node`

A node of the BigOrderedMap.

Expand All @@ -109,11 +110,19 @@ Basically - Leaf node is a single-resource OrderedMap, containing as much key/va
So Leaf node contains multiple values, not just one.


<pre><code><b>struct</b> <a href="big_ordered_map.md#0x1_big_ordered_map_Node">Node</a>&lt;K: store, V: store&gt; <b>has</b> store
<pre><code>enum <a href="big_ordered_map.md#0x1_big_ordered_map_Node">Node</a>&lt;K: store, V: store&gt; <b>has</b> store
</code></pre>



<details>
<summary>Variants</summary>


<details>
<summary>V1</summary>


<details>
<summary>Fields</summary>

Expand Down Expand Up @@ -146,6 +155,10 @@ So Leaf node contains multiple values, not just one.
</dl>


</details>

</details>

</details>

<a id="0x1_big_ordered_map_Child"></a>
Expand Down Expand Up @@ -531,7 +544,7 @@ it is required to use new_with_config, to explicitly select automatic or specifi
<a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_invalid_argument">error::invalid_argument</a>(<a href="big_ordered_map.md#0x1_big_ordered_map_EINVALID_CONFIG_PARAMETER">EINVALID_CONFIG_PARAMETER</a>)
);

<a href="big_ordered_map.md#0x1_big_ordered_map_new_with_config">new_with_config</a>(0, 0, <b>false</b>, 0)
<a href="big_ordered_map.md#0x1_big_ordered_map_new_with_config">new_with_config</a>(0, 0, <b>false</b>)
}
</code></pre>

Expand All @@ -553,7 +566,7 @@ If keys or values have variable size, and first element could be non-representat
it is important to compute and pass inner_max_degree and leaf_max_degree based on the largest element you want to be able to insert.


<pre><code><b>public</b> <b>fun</b> <a href="big_ordered_map.md#0x1_big_ordered_map_new_with_config">new_with_config</a>&lt;K: store, V: store&gt;(inner_max_degree: u16, leaf_max_degree: u16, reuse_slots: bool, num_to_preallocate: u32): <a href="big_ordered_map.md#0x1_big_ordered_map_BigOrderedMap">big_ordered_map::BigOrderedMap</a>&lt;K, V&gt;
<pre><code><b>public</b> <b>fun</b> <a href="big_ordered_map.md#0x1_big_ordered_map_new_with_config">new_with_config</a>&lt;K: store, V: store&gt;(inner_max_degree: u16, leaf_max_degree: u16, reuse_slots: bool): <a href="big_ordered_map.md#0x1_big_ordered_map_BigOrderedMap">big_ordered_map::BigOrderedMap</a>&lt;K, V&gt;
</code></pre>


Expand All @@ -562,16 +575,15 @@ it is important to compute and pass inner_max_degree and leaf_max_degree based o
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="big_ordered_map.md#0x1_big_ordered_map_new_with_config">new_with_config</a>&lt;K: store, V: store&gt;(inner_max_degree: u16, leaf_max_degree: u16, reuse_slots: bool, num_to_preallocate: u32): <a href="big_ordered_map.md#0x1_big_ordered_map_BigOrderedMap">BigOrderedMap</a>&lt;K, V&gt; {
<pre><code><b>public</b> <b>fun</b> <a href="big_ordered_map.md#0x1_big_ordered_map_new_with_config">new_with_config</a>&lt;K: store, V: store&gt;(inner_max_degree: u16, leaf_max_degree: u16, reuse_slots: bool): <a href="big_ordered_map.md#0x1_big_ordered_map_BigOrderedMap">BigOrderedMap</a>&lt;K, V&gt; {
<b>assert</b>!(inner_max_degree == 0 || (inner_max_degree &gt;= <a href="big_ordered_map.md#0x1_big_ordered_map_DEFAULT_INNER_MIN_DEGREE">DEFAULT_INNER_MIN_DEGREE</a> && (inner_max_degree <b>as</b> u64) &lt;= <a href="big_ordered_map.md#0x1_big_ordered_map_MAX_DEGREE">MAX_DEGREE</a>), <a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_invalid_argument">error::invalid_argument</a>(<a href="big_ordered_map.md#0x1_big_ordered_map_EINVALID_CONFIG_PARAMETER">EINVALID_CONFIG_PARAMETER</a>));
<b>assert</b>!(leaf_max_degree == 0 || (leaf_max_degree &gt;= <a href="big_ordered_map.md#0x1_big_ordered_map_DEFAULT_LEAF_MIN_DEGREE">DEFAULT_LEAF_MIN_DEGREE</a> && (leaf_max_degree <b>as</b> u64) &lt;= <a href="big_ordered_map.md#0x1_big_ordered_map_MAX_DEGREE">MAX_DEGREE</a>), <a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_invalid_argument">error::invalid_argument</a>(<a href="big_ordered_map.md#0x1_big_ordered_map_EINVALID_CONFIG_PARAMETER">EINVALID_CONFIG_PARAMETER</a>));
<b>assert</b>!(reuse_slots || num_to_preallocate == 0, <a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_invalid_argument">error::invalid_argument</a>(<a href="big_ordered_map.md#0x1_big_ordered_map_EINVALID_CONFIG_PARAMETER">EINVALID_CONFIG_PARAMETER</a>));

// Assert that <a href="../../aptos-stdlib/doc/storage_slots_allocator.md#0x1_storage_slots_allocator">storage_slots_allocator</a> special indices are aligned:
<b>assert</b>!(<a href="../../aptos-stdlib/doc/storage_slots_allocator.md#0x1_storage_slots_allocator_is_null_index">storage_slots_allocator::is_null_index</a>(<a href="big_ordered_map.md#0x1_big_ordered_map_NULL_INDEX">NULL_INDEX</a>), <a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_invalid_state">error::invalid_state</a>(<a href="big_ordered_map.md#0x1_big_ordered_map_EINTERNAL_INVARIANT_BROKEN">EINTERNAL_INVARIANT_BROKEN</a>));
<b>assert</b>!(<a href="../../aptos-stdlib/doc/storage_slots_allocator.md#0x1_storage_slots_allocator_is_special_unused_index">storage_slots_allocator::is_special_unused_index</a>(<a href="big_ordered_map.md#0x1_big_ordered_map_ROOT_INDEX">ROOT_INDEX</a>), <a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_invalid_state">error::invalid_state</a>(<a href="big_ordered_map.md#0x1_big_ordered_map_EINTERNAL_INVARIANT_BROKEN">EINTERNAL_INVARIANT_BROKEN</a>));

<b>let</b> nodes = <a href="../../aptos-stdlib/doc/storage_slots_allocator.md#0x1_storage_slots_allocator_new">storage_slots_allocator::new</a>(<a href="../../aptos-stdlib/doc/storage_slots_allocator.md#0x1_storage_slots_allocator_new_config">storage_slots_allocator::new_config</a>(reuse_slots, num_to_preallocate));
<b>let</b> nodes = <a href="../../aptos-stdlib/doc/storage_slots_allocator.md#0x1_storage_slots_allocator_new">storage_slots_allocator::new</a>(reuse_slots);

<b>let</b> self = BigOrderedMap::BPlusTreeMap {
root: <a href="big_ordered_map.md#0x1_big_ordered_map_new_node">new_node</a>(/*is_leaf=*/<b>true</b>),
Expand Down Expand Up @@ -646,6 +658,34 @@ Destroys the map if it's empty, otherwise aborts.



</details>

<a id="0x1_big_ordered_map_allocate_spare_slots"></a>

## Function `allocate_spare_slots`

Map was created with reuse_slots=true, you can allocate spare slots, to pay storage fee now, to
allow future insertions to not require any storage slot creation - making their gas more predictable
and better bounded/fair.
(otherwsie, unlucky inserts create new storage slots and are charge more for it)


<pre><code><b>public</b> <b>fun</b> <a href="big_ordered_map.md#0x1_big_ordered_map_allocate_spare_slots">allocate_spare_slots</a>&lt;K: store, V: store&gt;(self: &<b>mut</b> <a href="big_ordered_map.md#0x1_big_ordered_map_BigOrderedMap">big_ordered_map::BigOrderedMap</a>&lt;K, V&gt;, num_to_allocate: u64)
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="big_ordered_map.md#0x1_big_ordered_map_allocate_spare_slots">allocate_spare_slots</a>&lt;K: store, V: store&gt;(self: &<b>mut</b> <a href="big_ordered_map.md#0x1_big_ordered_map_BigOrderedMap">BigOrderedMap</a>&lt;K, V&gt;, num_to_allocate: u64) {
self.nodes.<a href="big_ordered_map.md#0x1_big_ordered_map_allocate_spare_slots">allocate_spare_slots</a>(num_to_allocate)
}
</code></pre>



</details>

<a id="0x1_big_ordered_map_add"></a>
Expand Down Expand Up @@ -1592,7 +1632,7 @@ Borrow a node mutably, given an index. Works for both root (i.e. inline) node an


<pre><code><b>fun</b> <a href="big_ordered_map.md#0x1_big_ordered_map_destroy_empty_node">destroy_empty_node</a>&lt;K: store, V: store&gt;(self: <a href="big_ordered_map.md#0x1_big_ordered_map_Node">Node</a>&lt;K, V&gt;) {
<b>let</b> <a href="big_ordered_map.md#0x1_big_ordered_map_Node">Node</a> { children, is_leaf: _, prev: _, next: _ } = self;
<b>let</b> Node::V1 { children, is_leaf: _, prev: _, next: _ } = self;
<b>assert</b>!(children.<a href="big_ordered_map.md#0x1_big_ordered_map_is_empty">is_empty</a>(), <a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_invalid_argument">error::invalid_argument</a>(<a href="big_ordered_map.md#0x1_big_ordered_map_EMAP_NOT_EMPTY">EMAP_NOT_EMPTY</a>));
children.<a href="big_ordered_map.md#0x1_big_ordered_map_destroy_empty">destroy_empty</a>();
}
Expand All @@ -1618,7 +1658,7 @@ Borrow a node mutably, given an index. Works for both root (i.e. inline) node an


<pre><code><b>fun</b> <a href="big_ordered_map.md#0x1_big_ordered_map_new_node">new_node</a>&lt;K: store, V: store&gt;(is_leaf: bool): <a href="big_ordered_map.md#0x1_big_ordered_map_Node">Node</a>&lt;K, V&gt; {
<a href="big_ordered_map.md#0x1_big_ordered_map_Node">Node</a> {
Node::V1 {
is_leaf: is_leaf,
children: <a href="ordered_map.md#0x1_ordered_map_new">ordered_map::new</a>(),
prev: <a href="big_ordered_map.md#0x1_big_ordered_map_NULL_INDEX">NULL_INDEX</a>,
Expand Down Expand Up @@ -1647,7 +1687,7 @@ Borrow a node mutably, given an index. Works for both root (i.e. inline) node an


<pre><code><b>fun</b> <a href="big_ordered_map.md#0x1_big_ordered_map_new_node_with_children">new_node_with_children</a>&lt;K: store, V: store&gt;(is_leaf: bool, children: OrderedMap&lt;K, <a href="big_ordered_map.md#0x1_big_ordered_map_Child">Child</a>&lt;V&gt;&gt;): <a href="big_ordered_map.md#0x1_big_ordered_map_Node">Node</a>&lt;K, V&gt; {
<a href="big_ordered_map.md#0x1_big_ordered_map_Node">Node</a> {
Node::V1 {
is_leaf: is_leaf,
children: children,
prev: <a href="big_ordered_map.md#0x1_big_ordered_map_NULL_INDEX">NULL_INDEX</a>,
Expand Down Expand Up @@ -2275,7 +2315,7 @@ Given a path to node (excluding the node itself), which is currently stored unde
// But append <b>to</b> the node <b>with</b> smaller keys, <b>as</b> <a href="ordered_map.md#0x1_ordered_map_append">ordered_map::append</a> is more efficient when adding <b>to</b> the end.
<b>let</b> (key_to_remove, reserved_slot_to_remove) = <b>if</b> (sibling_index == next) {
// destroying larger sibling node, keeping sibling_slot.
<b>let</b> <a href="big_ordered_map.md#0x1_big_ordered_map_Node">Node</a> { children: sibling_children, is_leaf: _, prev: _, next: sibling_next } = sibling_node;
<b>let</b> Node::V1 { children: sibling_children, is_leaf: _, prev: _, next: sibling_next } = sibling_node;
<b>let</b> key_to_remove = *children.<a href="big_ordered_map.md#0x1_big_ordered_map_new_end_iter">new_end_iter</a>().<a href="big_ordered_map.md#0x1_big_ordered_map_iter_prev">iter_prev</a>(children).<a href="big_ordered_map.md#0x1_big_ordered_map_iter_borrow_key">iter_borrow_key</a>(children);
children.append_disjoint(sibling_children);
node.next = sibling_next;
Expand All @@ -2300,7 +2340,7 @@ Given a path to node (excluding the node itself), which is currently stored unde
(key_to_remove, node_slot)
} <b>else</b> {
// destroying larger current node, keeping node_slot
<b>let</b> <a href="big_ordered_map.md#0x1_big_ordered_map_Node">Node</a> { children: node_children, is_leaf: _, prev: _, next: node_next } = node;
<b>let</b> Node::V1 { children: node_children, is_leaf: _, prev: _, next: node_next } = node;
<b>let</b> key_to_remove = *sibling_children.<a href="big_ordered_map.md#0x1_big_ordered_map_new_end_iter">new_end_iter</a>().<a href="big_ordered_map.md#0x1_big_ordered_map_iter_prev">iter_prev</a>(sibling_children).<a href="big_ordered_map.md#0x1_big_ordered_map_iter_borrow_key">iter_borrow_key</a>(sibling_children);
sibling_children.append_disjoint(node_children);
sibling_node.next = node_next;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@
<b>let</b> addr = <a href="../../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer_address_of">signer::address_of</a>(master);
<b>if</b> (!<b>exists</b>&lt;<a href="permissioned_delegation.md#0x1_permissioned_delegation_RegisteredDelegations">RegisteredDelegations</a>&gt;(addr)) {
<b>move_to</b>(master, <a href="permissioned_delegation.md#0x1_permissioned_delegation_RegisteredDelegations">RegisteredDelegations</a> {
delegations: <a href="big_ordered_map.md#0x1_big_ordered_map_new_with_config">big_ordered_map::new_with_config</a>(50, 20, <b>false</b>, 0)
delegations: <a href="big_ordered_map.md#0x1_big_ordered_map_new_with_config">big_ordered_map::new_with_config</a>(50, 20, <b>false</b>)
});
};
<b>let</b> handles = &<b>mut</b> <b>borrow_global_mut</b>&lt;<a href="permissioned_delegation.md#0x1_permissioned_delegation_RegisteredDelegations">RegisteredDelegations</a>&gt;(addr).delegations;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,7 @@ initialize permission storage by putting an empty storage under the address.
<b>move_to</b>(
&<a href="create_signer.md#0x1_create_signer">create_signer</a>(permissions_storage_addr),
// Each key is ~100bytes, the value is 12 bytes.
PermissionStorage::V1 { perms: <a href="big_ordered_map.md#0x1_big_ordered_map_new_with_config">big_ordered_map::new_with_config</a>(40, 35, <b>false</b>, 0) }
PermissionStorage::V1 { perms: <a href="big_ordered_map.md#0x1_big_ordered_map_new_with_config">big_ordered_map::new_with_config</a>(40, 35, <b>false</b>) }
);
}
</code></pre>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ module aptos_framework::permissioned_delegation {
let addr = signer::address_of(master);
if (!exists<RegisteredDelegations>(addr)) {
move_to(master, RegisteredDelegations {
delegations: big_ordered_map::new_with_config(50, 20, false, 0)
delegations: big_ordered_map::new_with_config(50, 20, false)
});
};
let handles = &mut borrow_global_mut<RegisteredDelegations>(addr).delegations;
Expand Down
Loading
Loading