Skip to content

Commit

Permalink
chore: stabilize Vector and improve docs (#815)
Browse files Browse the repository at this point in the history
  • Loading branch information
austinabell authored Aug 23, 2022
1 parent cb77463 commit 3c32d4f
Show file tree
Hide file tree
Showing 20 changed files with 199 additions and 39 deletions.
1 change: 1 addition & 0 deletions examples/abi/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions examples/callback-results/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions examples/cross-contract-calls/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions examples/factory-contract/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions examples/fungible-token/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions examples/lockable-fungible-token/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions examples/mission-control/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions examples/non-fungible-token/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions examples/status-message-collections/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions examples/status-message/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions examples/test-contract/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions near-sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ schemars = { version = "0.8.8", optional = true }
wee_alloc = { version = "0.4.5", default-features = false, optional = true }

# Used for caching, might be worth porting only functionality needed.
once_cell = { version = "1.8", optional = true, default-features = false }
once_cell = { version = "1.8", default-features = false }

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
# alt_bn128 feature will need to be removed on the next version update (now stabilized)
Expand All @@ -51,7 +51,7 @@ hex = { version = "0.4.3", features = ["serde"] }
[features]
default = ["wee_alloc", "unit-testing"]
expensive-debug = []
unstable = ["once_cell"]
unstable = []
abi = ["schemars", "near-sdk-macros/abi"]
unit-testing = ["near-vm-logic", "near-primitives-core", "near-primitives", "near-crypto"]

Expand Down
19 changes: 19 additions & 0 deletions near-sdk/src/collections/vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use std::marker::PhantomData;
use borsh::{BorshDeserialize, BorshSerialize};

use crate::collections::append_slice;
use crate::store::IndexMap;
use crate::{env, IntoStorageKey};

const ERR_INCONSISTENT_STATE: &str = "The collection is an inconsistent state. Did previous smart contract execution terminate unexpectedly?";
Expand Down Expand Up @@ -54,6 +55,24 @@ impl<T> Vector<T> {
Self { len: 0, prefix: prefix.into_storage_key(), el: PhantomData }
}

/// Helper utility to be able to easily migrate to the new [`Vector`] implementation.
///
/// This new [`Vector`]'s API matches the Rust [`Vec`] API more closely and has a caching
/// layer to avoid reading/writing redundant times to storage.
///
/// [`Vector`]: crate::store::Vector
#[cfg(feature = "unstable")]
pub fn to_v2(&self) -> crate::store::Vector<T>
where
T: BorshSerialize,
{
crate::store::Vector {
// Length cannot feasibly exceed u32::MAX, but checked conversion anyway.
len: self.len.try_into().unwrap(),
values: IndexMap::new(self.prefix.as_slice()),
}
}

fn index_to_lookup_key(&self, index: u64) -> Vec<u8> {
append_slice(&self.prefix, &index.to_le_bytes()[..])
}
Expand Down
1 change: 0 additions & 1 deletion near-sdk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ pub use near_sdk_macros::{
ext_contract, metadata, near_bindgen, BorshStorageKey, FunctionError, PanicOnDefault,
};

#[cfg(feature = "unstable")]
pub mod store;

pub mod collections;
Expand Down
3 changes: 2 additions & 1 deletion near-sdk/src/store/index_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ where
}

/// Inserts a element at `index`, returns the evicted element.
#[cfg(feature = "unstable")]
pub fn insert(&mut self, index: u32, element: T) -> Option<T> {
self.get_mut_inner(index).replace(Some(element))
}
Expand All @@ -160,7 +161,7 @@ where
}
}

#[cfg(not(target_arch = "wasm32"))]
#[cfg(all(not(target_arch = "wasm32"), feature = "unstable"))]
#[cfg(test)]
mod tests {
use super::IndexMap;
Expand Down
61 changes: 61 additions & 0 deletions near-sdk/src/store/mod.rs
Original file line number Diff line number Diff line change
@@ -1,38 +1,99 @@
//! Collections and types used when interacting with storage.
//!
//! This module is the updated version of [`near_sdk::collections`](crate::collections) where the
//! data structures are more optimized and have a closer API to [`std::collections`].
//!
//! These collections are more scalable versions of [`std::collections`] when used as contract
//! state because it allows values to be lazily loaded and stored based on what is actually
//! interacted with.
//!
//! The collections are as follows:
//!
//! Sequences:
//!
//! - [`Vector`]: Analogous to [`Vec`] but not contiguous and persisted to storage.
//!
//! Maps:
//!
//! - [`LookupMap`] (`unstable`): Wrapper around key-value storage interactions, similar to
//! [`UnorderedMap`]/[`std::collections::HashMap`] except that keys are not persisted and cannot be
//! iterated over.
//!
//! - [`UnorderedMap`] (`unstable`): Storage version of [`std::collections::HashMap`]. No ordering
//! guarantees.
//!
//! - [`TreeMap`] (`unstable`): Storage version of [`std::collections::BTreeMap`]. Ordered by key,
//! which comes at the cost of more expensive lookups and iteration.
//!
//! Sets:
//!
//! - [`LookupSet`] (`unstable`): Non-iterable storage version of [`std::collections::HashSet`].
//!
//! - [`UnorderedSet`] (`unstable`): Analogous to [`std::collections::HashSet`], and is an iterable
//! version of [`LookupSet`] and persisted to storage.
//!
//! Basic Types:
//!
//! - [`Lazy<T>`](Lazy) (`unstable`): Lazily loaded type that can be used in place of a type `T`.
//! Will only be loaded when interacted with and will persist on [`Drop`].
//!
//! - [`LazyOption<T>`](LazyOption) (`unstable`): Lazily loaded, optional type that can be used in
//! place of a type [`Option<T>`](Option). Will only be loaded when interacted with and will
//! persist on [`Drop`].
#[cfg(feature = "unstable")]
mod lazy;
#[cfg(feature = "unstable")]
pub use lazy::Lazy;

#[cfg(feature = "unstable")]
mod lazy_option;
#[cfg(feature = "unstable")]
pub use lazy_option::LazyOption;

pub mod vec;
pub use vec::Vector;

#[cfg(feature = "unstable")]
pub mod lookup_map;
#[cfg(feature = "unstable")]
pub use self::lookup_map::LookupMap;

#[cfg(feature = "unstable")]
mod lookup_set;
#[cfg(feature = "unstable")]
pub use self::lookup_set::LookupSet;

#[cfg(feature = "unstable")]
pub mod unordered_map;
#[cfg(feature = "unstable")]
pub use self::unordered_map::UnorderedMap;

#[cfg(feature = "unstable")]
pub mod unordered_set;
#[cfg(feature = "unstable")]
pub use self::unordered_set::UnorderedSet;

#[cfg(feature = "unstable")]
pub mod tree_map;
#[cfg(feature = "unstable")]
pub use self::tree_map::TreeMap;

mod index_map;
pub(crate) use self::index_map::IndexMap;

#[cfg(feature = "unstable")]
pub(crate) mod free_list;
#[cfg(feature = "unstable")]
pub(crate) use self::free_list::FreeList;

/// Storage key hash function types and trait to override map hash functions.
#[cfg(feature = "unstable")]
pub mod key;

pub(crate) const ERR_INCONSISTENT_STATE: &str =
"The collection is an inconsistent state. Did previous smart \
contract execution terminate unexpectedly?";

#[cfg(feature = "unstable")]
pub(crate) const ERR_NOT_EXIST: &str = "Key does not exist in map";
3 changes: 2 additions & 1 deletion near-sdk/src/store/unordered_set/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use std::fmt;
/// [`BorshDeserialize`] trait.
///
/// This set stores the values under a hash of the set's `prefix` and [`BorshSerialize`] of the
/// element using the set's [`CryptoHasher`] implementation.
/// element using the set's [`ToKey`] implementation.
///
/// The default hash function for [`UnorderedSet`] is [`Sha256`] which uses a syscall
/// (or host function) built into the NEAR runtime to hash the element. To use a custom function,
Expand Down Expand Up @@ -79,6 +79,7 @@ use std::fmt;
/// ```
///
/// [`with_hasher`]: Self::with_hasher
/// [`LookupSet`]: crate::store::LookupSet
#[derive(BorshDeserialize, BorshSerialize)]
pub struct UnorderedSet<T, H = Sha256>
where
Expand Down
Loading

0 comments on commit 3c32d4f

Please sign in to comment.