Smart Vector
The Smart Vector is a scalable vector implementation based on tables
, where elements are grouped into buckets. This data structure allows for efficient handling of large data sets by combining the flexibility of small vectors with the scalability of larger structures.
Core Features of SmartVector
Structure
The SmartVector
struct is designed to handle dynamic data with efficiency:
inline_vec
: A small vector that stores elements directly.big_vec
: An optional large vector for scalable storage.inline_capacity
: An optional value defining the capacity ofinline_vec
.bucket_size
: An optional value defining the size of buckets inbig_vec
.
Constants
The following constants define various error codes used within the module:
EINDEX_OUT_OF_BOUNDS
: 1EVECTOR_NOT_EMPTY
: 2EVECTOR_EMPTY
: 3EZERO_BUCKET_SIZE
: 4ESMART_VECTORS_LENGTH_MISMATCH
: 0x20005
API Overview
Creating Vectors
new<T: store>(): SmartVector<T>
: Creates an empty vector.empty_with_config<T: store>(inline_capacity: u64, bucket_size: u64): SmartVector<T>
: Creates an empty vector with custom capacity and bucket size.singleton<T: store>(element: T): SmartVector<T>
: Creates a vector with a single element.
Destroying Vectors
destroy_empty<T>(v: SmartVector<T>)
: Destroys an empty vector.destroy<T: drop>(v: SmartVector<T>)
: Destroys a vector and its elements.
Managing Elements
push_back<T: store>(v: &mut SmartVector<T>, val: T)
: Adds an element to the end of the vector.pop_back<T>(v: &mut SmartVector<T>): T
: Removes the last element from the vector.remove<T>(v: &mut SmartVector<T>, i: u64): T
: Removes an element at a specific index.swap_remove<T>(v: &mut SmartVector<T>, i: u64): T
: Swaps an element at a specific index with the last element and removes it.borrow<T>(v: &SmartVector<T>, i: u64): &T
: Returns an immutable reference to an element at a specific index.borrow_mut<T>(v: &mut SmartVector<T>, i: u64): &mut T
: Returns a mutable reference to an element at a specific index.
Utility Functions
length<T>(v: &SmartVector<T>): u64
: Returns the number of elements in the vector.is_empty<T>(v: &SmartVector<T>): bool
: Checks if the vector is empty.clear<T: drop>(v: &mut SmartVector<T>)
: Clears all elements from the vector.to_vector<T: store + copy>(v: &SmartVector<T>): vector<T>
: Converts a smart vector to a native vector.
Example Usage
Creating and Using a SmartVector
smart_vector.move
module 0x42::smart_vector_usage {
use aptos_std::smart_vector;
public entry fun main() {
let v = smart_vector::new<u64>();
smart_vector::push_back(&mut v, 10);
smart_vector::push_back(&mut v, 20);
let length = smart_vector::length(&v);
assert!(length == 2, 0);
let first_elem = smart_vector::borrow(&v, 0);
assert!(*first_elem == 10, 0);
let second_elem = smart_vector::borrow(&v, 1);
assert!(*second_elem == 20, 0);
let last_elem = smart_vector::pop_back(&mut v);
assert!(last_elem == 20, 0);
smart_vector::destroy_empty(v);
}
}
Appending Vectors
smart_vector.move
module 0x42::smart_vector_usage {
use aptos_std::smart_vector;
public fun append_vectors() {
let v1 = smart_vector::new<u64>();
let v2 = smart_vector::new<u64>();
smart_vector::push_back(&mut v1, 1);
smart_vector::push_back(&mut v1, 2);
smart_vector::push_back(&mut v2, 3);
smart_vector::push_back(&mut v2, 4);
smart_vector::append(&mut v1, v2);
let length = smart_vector::length(&v1);
assert!(length == 4, 0);
let first_elem = smart_vector::borrow(&v1, 0);
assert!(*first_elem == 1, 0);
let second_elem = smart_vector::borrow(&v1, 1);
assert!(*second_elem == 2, 0);
let third_elem = smart_vector::borrow(&v1, 2);
assert!(*third_elem == 3, 0);
let fourth_elem = smart_vector::borrow(&v1, 3);
assert!(*fourth_elem == 4, 0);
}
}
Removing Elements
smart_vector.move
module 0x42::smart_vector_usage {
use aptos_std::smart_vector;
public fun remove_elements() {
let v = smart_vector::new<u64>();
smart_vector::push_back(&mut v, 1);
smart_vector::push_back(&mut v, 2);
smart_vector::push_back(&mut v, 3);
let removed_elem = smart_vector::remove(&mut v, 1);
assert!(removed_elem == 2, 0);
let length = smart_vector::length(&v);
assert!(length == 2, 0);
let first_elem = smart_vector::borrow(&v, 0);
assert!(*first_elem == 1, 0);
let second_elem = smart_vector::borrow(&v, 1);
assert!(*second_elem == 3, 0);
}
}
Clearing the Vector
smart_vector.move
module 0x42::smart_vector_usage {
use aptos_std::smart_vector;
public fun clear_vector() {
let v = smart_vector::new<u64>();
smart_vector::push_back(&mut v, 1);
smart_vector::push_back(&mut v, 2);
smart_vector::push_back(&mut v, 3);
smart_vector::clear(&mut v);
let length = smart_vector::length(&v);
assert!(length == 0, 0);
}
}
Swapping Elements
smart_vector.move
module 0x42::smart_vector_usage {
use aptos_std::smart_vector;
public fun swap_elements() {
let v = smart_vector::new<u64>();
smart_vector::push_back(&mut v, 1);
smart_vector::push_back(&mut v, 2);
smart_vector::push_back(&mut v, 3);
smart_vector::swap(&mut v, 0, 2);
let first_elem = smart_vector::borrow(&v, 0);
assert!(*first_elem == 3, 0);
let third_elem = smart_vector::borrow(&v, 2);
assert!(*third_elem == 1, 0);
}
}