Skip to content
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
7 changes: 2 additions & 5 deletions benchmarks/btreemap/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
use benchmarks::common::Random;
use benchmarks::{random::Random, vec::UnboundedVecN};
use canbench_rs::{bench, bench_fn, BenchResult};
use ic_stable_structures::memory_manager::{MemoryId, MemoryManager};
use ic_stable_structures::{
storable::{Blob, UnboundedVecN},
BTreeMap, DefaultMemoryImpl, Memory, Storable,
};
use ic_stable_structures::{storable::Blob, BTreeMap, DefaultMemoryImpl, Memory, Storable};
use std::ops::Bound;
use tiny_rng::{Rand, Rng};

Expand Down
2 changes: 1 addition & 1 deletion benchmarks/compare/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use benchmarks::vec::BoundedVecN;
use canbench_rs::{bench, bench_fn};
use ic_cdk::api::stable::WASM_PAGE_SIZE_IN_BYTES;
use ic_stable_structures::{
memory_manager::{MemoryId, MemoryManager},
storable::BoundedVecN,
BTreeMap, DefaultMemoryImpl, Memory, Vec as StableVec,
};

Expand Down
3 changes: 2 additions & 1 deletion benchmarks/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod common;
pub mod random;
pub mod vec;
5 changes: 3 additions & 2 deletions benchmarks/src/common.rs → benchmarks/src/random.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use ic_stable_structures::storable::{Blob, BoundedVecN, Storable, UnboundedVecN};
use crate::vec::{BoundedVecN, UnboundedVecN};
use ic_stable_structures::storable::{Blob, Storable};
use tiny_rng::{Rand, Rng};

pub trait Random {
Expand All @@ -20,7 +21,7 @@ impl<const K: usize> Random for Blob<K> {

impl<const K: usize> Random for UnboundedVecN<K> {
fn random(rng: &mut Rng) -> Self {
let size = rng.rand_u32() % Self::max_size();
let size = rng.rand_u32() % Self::MAX_SIZE;
let mut buf = Vec::with_capacity(size as usize);
for _ in 0..size {
buf.push(rng.rand_u8());
Expand Down
87 changes: 87 additions & 0 deletions benchmarks/src/vec.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
use ic_stable_structures::storable::{Bound, Storable};
use std::borrow::Cow;

/// Unbounded vector of bytes, always of length `N`.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
pub struct UnboundedVecN<const N: usize>(Vec<u8>);

impl<const N: usize> UnboundedVecN<N> {
pub const MAX_SIZE: u32 = N as u32;

pub fn from(slice: &[u8]) -> Self {
assert!(
slice.len() <= N,
"expected a slice with length <= {} bytes, but found {} bytes",
N,
slice.len()
);
let mut vec = Vec::with_capacity(N);
vec.extend_from_slice(slice);
vec.resize(N, 0);
Self(vec)
}
}

impl<const N: usize> Default for UnboundedVecN<N> {
fn default() -> Self {
Self(vec![0; N])
}
}

impl<const N: usize> Storable for UnboundedVecN<N> {
fn to_bytes(&self) -> Cow<[u8]> {
Cow::Owned(self.0.clone())
}

#[inline]
fn from_bytes(bytes: Cow<[u8]>) -> Self {
Self(bytes.into_owned())
}

const BOUND: Bound = Bound::Unbounded;
}

/// Bounded vector of bytes, always of length `N`.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
pub struct BoundedVecN<const N: usize>(Vec<u8>);

impl<const N: usize> BoundedVecN<N> {
pub fn max_size() -> u32 {
Comment thread
maksymar marked this conversation as resolved.
N as u32
}

pub fn from(slice: &[u8]) -> Self {
assert!(
slice.len() <= N,
"expected a slice with length <= {} bytes, but found {} bytes",
N,
slice.len()
);
let mut vec = Vec::with_capacity(N);
vec.extend_from_slice(slice);
vec.resize(N, 0);
Self(vec)
}
}

impl<const N: usize> Default for BoundedVecN<N> {
fn default() -> Self {
Self(vec![0; N])
}
}

impl<const N: usize> Storable for BoundedVecN<N> {
fn to_bytes(&self) -> Cow<[u8]> {
Cow::Owned(self.0.clone())
}

#[inline]
fn from_bytes(bytes: Cow<[u8]>) -> Self {
Self(bytes.into_owned())
}

const BOUND: Bound = Bound::Bounded {
max_size: N as u32,
is_fixed_size: false,
};
}
2 changes: 1 addition & 1 deletion benchmarks/vec/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use benchmarks::common::Random;
use benchmarks::random::Random;
use canbench_rs::{bench, bench_fn, BenchResult};
use ic_stable_structures::memory_manager::{MemoryId, MemoryManager};
use ic_stable_structures::storable::Blob;
Expand Down
8 changes: 2 additions & 6 deletions src/storable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,7 @@ impl<const N: usize> Storable for Blob<N> {
pub struct UnboundedVecN<const N: usize>(Vec<u8>);

impl<const N: usize> UnboundedVecN<N> {
pub fn max_size() -> u32 {
N as u32
}
pub const MAX_SIZE: u32 = N as u32;

pub fn from(slice: &[u8]) -> Self {
assert!(
Expand Down Expand Up @@ -237,9 +235,7 @@ impl<const N: usize> Storable for UnboundedVecN<N> {
pub struct BoundedVecN<const N: usize>(Vec<u8>);

impl<const N: usize> BoundedVecN<N> {
pub fn max_size() -> u32 {
N as u32
}
pub const MAX_SIZE: u32 = N as u32;

pub fn from(slice: &[u8]) -> Self {
assert!(
Expand Down