From 3e0522b86d3e2e86fc0857f71ded91246078a127 Mon Sep 17 00:00:00 2001 From: austinabell Date: Thu, 18 Nov 2021 15:31:11 +0000 Subject: [PATCH 1/2] fix(vector): Update legacy vector to optimize nth operations on iterators --- near-sdk/src/collections/mod.rs | 2 +- near-sdk/src/collections/vector.rs | 144 +++++++++++++++++++++++++++-- 2 files changed, 138 insertions(+), 8 deletions(-) diff --git a/near-sdk/src/collections/mod.rs b/near-sdk/src/collections/mod.rs index af7c9e014..14fa3c769 100644 --- a/near-sdk/src/collections/mod.rs +++ b/near-sdk/src/collections/mod.rs @@ -44,7 +44,7 @@ pub use lookup_map::LookupMap; mod lookup_set; pub use lookup_set::LookupSet; -mod vector; +pub mod vector; pub use vector::Vector; mod unordered_map; diff --git a/near-sdk/src/collections/vector.rs b/near-sdk/src/collections/vector.rs index a100aafc8..350bf5c3a 100644 --- a/near-sdk/src/collections/vector.rs +++ b/near-sdk/src/collections/vector.rs @@ -1,5 +1,7 @@ //! A vector implemented on a trie. Unlike standard vector does not support insertion and removal //! of an element results in the last element being placed in the empty position. +use core::ops::Range; +use std::iter::FusedIterator; use std::marker::PhantomData; use borsh::{BorshDeserialize, BorshSerialize}; @@ -126,11 +128,8 @@ impl Vector { } /// Iterate over raw serialized elements. - pub fn iter_raw(&self) -> impl Iterator> + '_ { - (0..self.len).map(move |i| { - let lookup_key = self.index_to_lookup_key(i); - expect_consistent_state(env::storage_read(&lookup_key)) - }) + pub fn iter_raw(&self) -> RawIter { + RawIter::new(self) } /// Extends vector from the given collection of serialized elements. @@ -206,8 +205,8 @@ where } /// Iterate over deserialized elements. - pub fn iter(&self) -> impl Iterator + '_ { - self.iter_raw().map(|raw_element| Self::deserialize_element(&raw_element)) + pub fn iter(&self) -> Iter { + Iter::new(self) } pub fn to_vec(&self) -> Vec { @@ -237,6 +236,110 @@ impl std::fmt::Debug for Vector { } } +/// An iterator over raw serialized bytes of each element in the [`Vector`]. +pub struct RawIter<'a, T> { + vec: &'a Vector, + range: Range, +} + +impl<'a, T> RawIter<'a, T> { + fn new(vec: &'a Vector) -> Self { + Self { vec, range: Range { start: 0, end: vec.len() } } + } + + /// Returns number of elements left to iterate. + fn remaining(&self) -> usize { + (self.range.end - self.range.start) as usize + } +} + +impl<'a, T> Iterator for RawIter<'a, T> { + type Item = Vec; + + fn next(&mut self) -> Option { + ::nth(self, 0) + } + + fn size_hint(&self) -> (usize, Option) { + let remaining = self.remaining(); + (remaining, Some(remaining)) + } + + fn count(self) -> usize { + self.remaining() + } + + fn nth(&mut self, n: usize) -> Option { + let idx = self.range.nth(n)?; + self.vec.get_raw(idx) + } +} + +impl<'a, T> ExactSizeIterator for RawIter<'a, T> {} +impl<'a, T> FusedIterator for RawIter<'a, T> {} + +impl<'a, T> DoubleEndedIterator for RawIter<'a, T> { + fn next_back(&mut self) -> Option { + ::nth_back(self, 0) + } + + fn nth_back(&mut self, n: usize) -> Option { + let idx = self.range.nth_back(n)?; + self.vec.get_raw(idx) + } +} + +/// An iterator over each element deserialized in the [`Vector`]. +pub struct Iter<'a, T> { + inner: RawIter<'a, T>, +} + +impl<'a, T> Iter<'a, T> { + fn new(vec: &'a Vector) -> Self { + Self { inner: RawIter::new(vec) } + } +} + +impl<'a, T> Iterator for Iter<'a, T> +where + T: BorshDeserialize, +{ + type Item = T; + + fn next(&mut self) -> Option { + ::nth(self, 0) + } + + fn size_hint(&self) -> (usize, Option) { + let remaining = self.inner.remaining(); + (remaining, Some(remaining)) + } + + fn count(self) -> usize { + self.inner.remaining() + } + + fn nth(&mut self, n: usize) -> Option { + self.inner.nth(n).map(|raw_element| Vector::deserialize_element(&raw_element)) + } +} + +impl<'a, T> ExactSizeIterator for Iter<'a, T> where T: BorshDeserialize {} +impl<'a, T> FusedIterator for Iter<'a, T> where T: BorshDeserialize {} + +impl<'a, T> DoubleEndedIterator for Iter<'a, T> +where + T: BorshDeserialize, +{ + fn next_back(&mut self) -> Option { + ::nth_back(self, 0) + } + + fn nth_back(&mut self, n: usize) -> Option { + self.inner.nth_back(n).map(|raw_element| Vector::deserialize_element(&raw_element)) + } +} + #[cfg(not(target_arch = "wasm32"))] #[cfg(test)] mod tests { @@ -393,4 +496,31 @@ mod tests { ); } } + + #[test] + pub fn iterator_checks() { + let mut vec = Vector::new(b"v"); + let mut baseline = vec![]; + for i in 0..10 { + vec.push(&i); + baseline.push(i); + } + + let mut vec_iter = vec.iter(); + let mut bl_iter = baseline.iter(); + assert_eq!(vec_iter.next(), bl_iter.next().copied()); + assert_eq!(vec_iter.next_back(), bl_iter.next_back().copied()); + assert_eq!(vec_iter.nth(3), bl_iter.nth(3).copied()); + assert_eq!(vec_iter.nth_back(2), bl_iter.nth_back(2).copied()); + + // Check to make sure indexing overflow is handled correctly + assert!(vec_iter.nth(5).is_none()); + assert!(bl_iter.nth(5).is_none()); + + assert!(vec_iter.next().is_none()); + assert!(bl_iter.next().is_none()); + + // Count check + assert_eq!(vec.iter().count(), baseline.len()); + } } From 348acf4424824fb4be8eb12136ead6d8ea4fe305 Mon Sep 17 00:00:00 2001 From: austinabell Date: Thu, 18 Nov 2021 16:54:23 +0000 Subject: [PATCH 2/2] rebuild --- .../res/non_fungible_token.wasm | Bin 287360 -> 287058 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/examples/non-fungible-token/res/non_fungible_token.wasm b/examples/non-fungible-token/res/non_fungible_token.wasm index 8fedca17040d26d070bb66c4a8fe542a87aa4970..07bd7d8b7317ef15f89fdd5915600e6037820f38 100755 GIT binary patch delta 32375 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 delta 32567 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