Skip to content
🎉 Welcome to the new Aptos Docs! Click here to submit feedback!

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 of inline_vec.
  • bucket_size: An optional value defining the size of buckets in big_vec.

Constants

The following constants define various error codes used within the module:

  • EINDEX_OUT_OF_BOUNDS: 1
  • EVECTOR_NOT_EMPTY: 2
  • EVECTOR_EMPTY: 3
  • EZERO_BUCKET_SIZE: 4
  • ESMART_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);
    }
}

Source Code

Other Examples