Skip to content

Commit

Permalink
[move][stdlib] Add efficient BigOrderedMap implementation (#14753)
Browse files Browse the repository at this point in the history
## Description
Having efficient and concurrent large-sized "Map" and "OrderedMap" implementations is useful across variety of needs.

Current SmartTable implementation has various limitations, from it being sequential, to it not having smart ways to deal with collisions. It cannot be improved - as the structs are unmodifiable, and so should be deprecated fully.

In this PR:
* provide efficient big "OrderedMap" implementation. BPlusTreeMap is chosen as it is best suited for the onchain storage layout - where majority of cost comes from loading and writing to storage items, and there is no partial read/write of them. It also rebalances in a way that reduces amount writes needed 
* writing to keys that are not close enough, to a BPlusTreeMap with multiple layers, is generally parallel. More elements in the BPlusTreeMap, the more operations will be parallel. 
* it is an enum, so can be evolved in the future as needed
* has an option to pre-pay and pre-allocate storage slots, and to reuse them, achieving predictable gas charges.
  * defined potentially generally useful StorageSlotsAllocator, to manage indexed storage slots for datastructures that need it. Easier to use and more flexible/configurable than directly using Table. (which is also an enum, and so can be evolved / new strategies can be added)
* keeps root note directly inside the resource, to reduce number of resources needed by 1, and optimizes operations when root is the leaf node.
* whenever key or value is inserted/modified, we check the size to make sure it is allowed (i.e. that it is smaller than max_node_size / max_degree). this requires bcs::serialized_size() call on every insert/upsert.
  * in case types have constant sizes, check is performed once, on construction, and then it’s skipped on insert/upsert
  • Loading branch information
igor-aptos authored and rahxephon89 committed Jan 13, 2025
1 parent 790aa55 commit 144224e
Show file tree
Hide file tree
Showing 23 changed files with 6,090 additions and 130 deletions.
11 changes: 3 additions & 8 deletions aptos-move/e2e-benchmark/data/calibration_values.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,6 @@ VectorRangeMove { vec_len: 3000, element_len: 1, index: 1000, move_len: 500, rep
VectorTrimAppend { vec_len: 100, element_len: 100, index: 0, repeats: 0 } 119 0.909 1.201 293.5
VectorTrimAppend { vec_len: 100, element_len: 100, index: 10, repeats: 1000 } 119 0.951 1.143 12571.2
VectorRangeMove { vec_len: 100, element_len: 100, index: 50, move_len: 10, repeats: 1000 } 6 0.925 1.001 5316.2
MapInsertRemove { len: 10, repeats: 0, use_simple_map: false } 6 0.925 1.001 378
MapInsertRemove { len: 10, repeats: 100, use_simple_map: false } 6 0.925 1.001 8184
MapInsertRemove { len: 10, repeats: 100, use_simple_map: true } 6 0.925 1.001 8201.7
MapInsertRemove { len: 100, repeats: 0, use_simple_map: false } 6 0.925 1.001 5094
MapInsertRemove { len: 100, repeats: 100, use_simple_map: false } 6 0.925 1.001 15838
MapInsertRemove { len: 100, repeats: 100, use_simple_map: true } 6 0.925 1.001 39802.4
MapInsertRemove { len: 1000, repeats: 0, use_simple_map: false } 6 0.925 1.001 66878
MapInsertRemove { len: 1000, repeats: 100, use_simple_map: false } 6 0.925 1.001 79826
MapInsertRemove { len: 100, repeats: 100, map_type: OrderedMap } 6 0.925 1.001 15838
MapInsertRemove { len: 100, repeats: 100, map_type: SimpleMap } 6 0.925 1.001 39802.4
MapInsertRemove { len: 1000, repeats: 100, map_type: OrderedMap } 6 0.925 1.001 79826
33 changes: 4 additions & 29 deletions aptos-move/e2e-benchmark/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use aptos_transaction_generator_lib::{
entry_point_trait::{AutomaticArgs, EntryPointTrait, MultiSigConfig},
publishing::publish_util::{Package, PackageHandler},
};
use aptos_transaction_workloads_lib::{EntryPoints, LoopType};
use aptos_transaction_workloads_lib::{EntryPoints, LoopType, MapType};
use aptos_types::{account_address::AccountAddress, transaction::TransactionPayload};
use rand::{rngs::StdRng, SeedableRng};
use serde_json::json;
Expand Down Expand Up @@ -238,45 +238,20 @@ fn main() {
move_len: 10,
repeats: 1000,
},
EntryPoints::MapInsertRemove {
len: 10,
repeats: 0,
use_simple_map: false,
},
EntryPoints::MapInsertRemove {
len: 10,
repeats: 100,
use_simple_map: false,
},
EntryPoints::MapInsertRemove {
len: 10,
repeats: 100,
use_simple_map: true,
},
EntryPoints::MapInsertRemove {
len: 100,
repeats: 0,
use_simple_map: false,
},
EntryPoints::MapInsertRemove {
len: 100,
repeats: 100,
use_simple_map: false,
map_type: MapType::OrderedMap,
},
EntryPoints::MapInsertRemove {
len: 100,
repeats: 100,
use_simple_map: true,
},
EntryPoints::MapInsertRemove {
len: 1000,
repeats: 0,
use_simple_map: false,
map_type: MapType::SimpleMap,
},
EntryPoints::MapInsertRemove {
len: 1000,
repeats: 100,
use_simple_map: false,
map_type: MapType::OrderedMap,
},
];

Expand Down
Loading

0 comments on commit 144224e

Please sign in to comment.