Skip to content

Commit e18b6d0

Browse files
Corrections to MapView after the introduction of ValueOrBytes. (#3046)
## Motivation Several additional suggestions were forgotten in the PR #3036 ## Proposal The following corrections were made: * The `ValueOrBytes` is marked as private. * The `count` used for `SetView`, `CollectionView`, `ReentrantCollectionView`, `MapView` and `KeyvalueStoreView` are `usize` which makes them architecture dependent. We switch to u32. * The `FnMut(I, V)` forces a clone which is not always needed. So, it was replaced by `FnMut(I, Cow<'a, V>)`. Actually, the clone still occurs, but if someone were to want to just access the reference, it would be possible. Unfortunately, the use of the Cow complexifies the call to the `for_each_key_value`. ## Test Plan The CI. ## Release Plan This is a breaking change with TestNEt / DevNet as it changes the hashes values. ## Links None.
1 parent 52d2a75 commit e18b6d0

File tree

9 files changed

+45
-28
lines changed

9 files changed

+45
-28
lines changed

examples/crowd-funding/src/contract.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ impl CrowdFundingContract {
175175
self.state
176176
.pledges
177177
.for_each_index_value(|pledger, amount| {
178+
let amount = amount.into_owned();
178179
pledges.push((pledger, amount));
179180
Ok(())
180181
})

examples/gen-nft/src/service.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ impl QueryRoot {
9494
self.non_fungible_token
9595
.nfts
9696
.for_each_index_value(|_token_id, nft| {
97+
let nft = nft.into_owned();
9798
let nft_output = NftOutput::new(nft);
9899
nfts.insert(nft_output.token_id.clone(), nft_output);
99100
Ok(())
@@ -121,6 +122,7 @@ impl QueryRoot {
121122
self.non_fungible_token
122123
.owned_token_ids
123124
.for_each_index_value(|owner, token_ids| {
125+
let token_ids = token_ids.into_owned();
124126
let new_token_ids = token_ids
125127
.into_iter()
126128
.map(|token_id| STANDARD_NO_PAD.encode(token_id.id))

examples/non-fungible/src/service.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ impl QueryRoot {
9696
self.non_fungible_token
9797
.nfts
9898
.for_each_index_value(|_token_id, nft| {
99+
let nft = nft.into_owned();
99100
let payload = {
100101
let mut runtime = self
101102
.runtime
@@ -130,6 +131,7 @@ impl QueryRoot {
130131
self.non_fungible_token
131132
.owned_token_ids
132133
.for_each_index_value(|owner, token_ids| {
134+
let token_ids = token_ids.into_owned();
133135
let new_token_ids = token_ids
134136
.into_iter()
135137
.map(|token_id| STANDARD_NO_PAD.encode(token_id.id))

linera-views/src/test_utils/test_views.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ impl TestView for TestMapView<MemoryContext<()>> {
226226
let mut state = HashMap::new();
227227
self.map
228228
.for_each_index_value(|key, value| {
229+
let value = value.into_owned();
229230
state.insert(key, value);
230231
Ok(())
231232
})

linera-views/src/views/collection_view.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -626,7 +626,8 @@ where
626626
let _hash_latency = COLLECTION_VIEW_HASH_RUNTIME.measure_latency();
627627
let mut hasher = sha3::Sha3_256::default();
628628
let keys = self.keys().await?;
629-
hasher.update_with_bcs_bytes(&keys.len())?;
629+
let count = keys.len() as u32;
630+
hasher.update_with_bcs_bytes(&count)?;
630631
let updates = self.updates.get_mut();
631632
for key in keys {
632633
hasher.update_with_bytes(&key)?;
@@ -654,7 +655,8 @@ where
654655
let _hash_latency = COLLECTION_VIEW_HASH_RUNTIME.measure_latency();
655656
let mut hasher = sha3::Sha3_256::default();
656657
let keys = self.keys().await?;
657-
hasher.update_with_bcs_bytes(&keys.len())?;
658+
let count = keys.len() as u32;
659+
hasher.update_with_bcs_bytes(&count)?;
658660
let updates = self.updates.read().await;
659661
for key in keys {
660662
hasher.update_with_bytes(&key)?;

linera-views/src/views/key_value_store_view.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1125,7 +1125,7 @@ where
11251125
#[cfg(with_metrics)]
11261126
let _hash_latency = KEY_VALUE_STORE_VIEW_HASH_LATENCY.measure_latency();
11271127
let mut hasher = sha3::Sha3_256::default();
1128-
let mut count = 0;
1128+
let mut count = 0u32;
11291129
self.for_each_index_value(|index, value| -> Result<(), ViewError> {
11301130
count += 1;
11311131
hasher.update_with_bytes(index)?;

linera-views/src/views/map_view.rs

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ static MAP_VIEW_HASH_RUNTIME: LazyLock<HistogramVec> = LazyLock::new(|| {
3737
});
3838

3939
use std::{
40-
borrow::Borrow,
40+
borrow::{Borrow, Cow},
4141
collections::{btree_map::Entry, BTreeMap},
4242
marker::PhantomData,
4343
mem,
@@ -67,7 +67,7 @@ pub struct ByteMapView<C, V> {
6767
}
6868

6969
/// Whether we have a value or its serialization.
70-
pub enum ValueOrBytes<'a, T> {
70+
enum ValueOrBytes<'a, T> {
7171
/// The value itself.
7272
Value(&'a T),
7373
/// The serialization.
@@ -78,11 +78,11 @@ impl<'a, T> ValueOrBytes<'a, T>
7878
where
7979
T: Clone + DeserializeOwned,
8080
{
81-
/// Convert to a value.
82-
pub fn to_value(self) -> Result<T, ViewError> {
81+
/// Convert to a Cow.
82+
fn to_value(&self) -> Result<Cow<'a, T>, ViewError> {
8383
match self {
84-
ValueOrBytes::Value(value) => Ok(value.clone()),
85-
ValueOrBytes::Bytes(bytes) => Ok(bcs::from_bytes(&bytes)?),
84+
ValueOrBytes::Value(value) => Ok(Cow::Borrowed(value)),
85+
ValueOrBytes::Bytes(bytes) => Ok(Cow::Owned(bcs::from_bytes(bytes)?)),
8686
}
8787
}
8888
}
@@ -92,7 +92,7 @@ where
9292
T: Serialize,
9393
{
9494
/// Convert to bytes.
95-
pub fn to_bytes(self) -> Result<Vec<u8>, ViewError> {
95+
pub fn into_bytes(self) -> Result<Vec<u8>, ViewError> {
9696
match self {
9797
ValueOrBytes::Value(value) => Ok(bcs::to_bytes(value)?),
9898
ValueOrBytes::Bytes(bytes) => Ok(bytes),
@@ -706,13 +706,13 @@ where
706706
/// assert_eq!(part_keys.len(), 2);
707707
/// # })
708708
/// ```
709-
pub async fn for_each_key_value_while<F>(
710-
&self,
709+
pub async fn for_each_key_value_while<'a, F>(
710+
&'a self,
711711
mut f: F,
712712
prefix: Vec<u8>,
713713
) -> Result<(), ViewError>
714714
where
715-
F: FnMut(&[u8], V) -> Result<bool, ViewError> + Send,
715+
F: FnMut(&[u8], Cow<'a, V>) -> Result<bool, ViewError> + Send,
716716
{
717717
self.for_each_key_value_or_bytes_while(
718718
|key, value| {
@@ -772,9 +772,13 @@ where
772772
/// assert_eq!(count, 1);
773773
/// # })
774774
/// ```
775-
pub async fn for_each_key_value<F>(&self, mut f: F, prefix: Vec<u8>) -> Result<(), ViewError>
775+
pub async fn for_each_key_value<'a, F>(
776+
&'a self,
777+
mut f: F,
778+
prefix: Vec<u8>,
779+
) -> Result<(), ViewError>
776780
where
777-
F: FnMut(&[u8], V) -> Result<(), ViewError> + Send,
781+
F: FnMut(&[u8], Cow<'a, V>) -> Result<(), ViewError> + Send,
778782
{
779783
self.for_each_key_value_while(
780784
|key, value| {
@@ -820,6 +824,7 @@ where
820824
|key, value| {
821825
let mut big_key = prefix.clone();
822826
big_key.extend(key);
827+
let value = value.into_owned();
823828
key_values.push((big_key, value));
824829
Ok(())
825830
},
@@ -917,13 +922,13 @@ where
917922
#[cfg(with_metrics)]
918923
let _hash_latency = MAP_VIEW_HASH_RUNTIME.measure_latency();
919924
let mut hasher = sha3::Sha3_256::default();
920-
let mut count = 0;
925+
let mut count = 0u32;
921926
let prefix = Vec::new();
922927
self.for_each_key_value_or_bytes(
923928
|index, value| {
924929
count += 1;
925930
hasher.update_with_bytes(index)?;
926-
let bytes = value.to_bytes()?;
931+
let bytes = value.into_bytes()?;
927932
hasher.update_with_bytes(&bytes)?;
928933
Ok(())
929934
},
@@ -1275,9 +1280,9 @@ where
12751280
/// assert_eq!(values.len(), 2);
12761281
/// # })
12771282
/// ```
1278-
pub async fn for_each_index_value_while<F>(&self, mut f: F) -> Result<(), ViewError>
1283+
pub async fn for_each_index_value_while<'a, F>(&'a self, mut f: F) -> Result<(), ViewError>
12791284
where
1280-
F: FnMut(I, V) -> Result<bool, ViewError> + Send,
1285+
F: FnMut(I, Cow<'a, V>) -> Result<bool, ViewError> + Send,
12811286
{
12821287
let prefix = Vec::new();
12831288
self.map
@@ -1312,9 +1317,9 @@ where
13121317
/// assert_eq!(count, 1);
13131318
/// # })
13141319
/// ```
1315-
pub async fn for_each_index_value<F>(&self, mut f: F) -> Result<(), ViewError>
1320+
pub async fn for_each_index_value<'a, F>(&'a self, mut f: F) -> Result<(), ViewError>
13161321
where
1317-
F: FnMut(I, V) -> Result<(), ViewError> + Send,
1322+
F: FnMut(I, Cow<'a, V>) -> Result<(), ViewError> + Send,
13181323
{
13191324
let prefix = Vec::new();
13201325
self.map
@@ -1356,6 +1361,7 @@ where
13561361
pub async fn index_values(&self) -> Result<Vec<(I, V)>, ViewError> {
13571362
let mut key_values = Vec::new();
13581363
self.for_each_index_value(|index, value| {
1364+
let value = value.into_owned();
13591365
key_values.push((index, value));
13601366
Ok(())
13611367
})
@@ -1771,9 +1777,9 @@ where
17711777
/// assert_eq!(values.len(), 2);
17721778
/// # })
17731779
/// ```
1774-
pub async fn for_each_index_value_while<F>(&self, mut f: F) -> Result<(), ViewError>
1780+
pub async fn for_each_index_value_while<'a, F>(&'a self, mut f: F) -> Result<(), ViewError>
17751781
where
1776-
F: FnMut(I, V) -> Result<bool, ViewError> + Send,
1782+
F: FnMut(I, Cow<'a, V>) -> Result<bool, ViewError> + Send,
17771783
{
17781784
let prefix = Vec::new();
17791785
self.map
@@ -1809,9 +1815,9 @@ where
18091815
/// assert_eq!(indices, vec![34, 37]);
18101816
/// # })
18111817
/// ```
1812-
pub async fn for_each_index_value<F>(&self, mut f: F) -> Result<(), ViewError>
1818+
pub async fn for_each_index_value<'a, F>(&'a self, mut f: F) -> Result<(), ViewError>
18131819
where
1814-
F: FnMut(I, V) -> Result<(), ViewError> + Send,
1820+
F: FnMut(I, Cow<'a, V>) -> Result<(), ViewError> + Send,
18151821
{
18161822
let prefix = Vec::new();
18171823
self.map
@@ -1853,6 +1859,7 @@ where
18531859
pub async fn index_values(&self) -> Result<Vec<(I, V)>, ViewError> {
18541860
let mut key_values = Vec::new();
18551861
self.for_each_index_value(|index, value| {
1862+
let value = value.into_owned();
18561863
key_values.push((index, value));
18571864
Ok(())
18581865
})

linera-views/src/views/reentrant_collection_view.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -983,7 +983,8 @@ where
983983
let _hash_latency = REENTRANT_COLLECTION_VIEW_HASH_RUNTIME.measure_latency();
984984
let mut hasher = sha3::Sha3_256::default();
985985
let keys = self.keys().await?;
986-
hasher.update_with_bcs_bytes(&keys.len())?;
986+
let count = keys.len() as u32;
987+
hasher.update_with_bcs_bytes(&count)?;
987988
let cached_entries = self.cached_entries.get_mut().unwrap();
988989
for key in keys {
989990
hasher.update_with_bytes(&key)?;
@@ -1016,7 +1017,8 @@ where
10161017
let _hash_latency = REENTRANT_COLLECTION_VIEW_HASH_RUNTIME.measure_latency();
10171018
let mut hasher = sha3::Sha3_256::default();
10181019
let keys = self.keys().await?;
1019-
hasher.update_with_bcs_bytes(&keys.len())?;
1020+
let count = keys.len() as u32;
1021+
hasher.update_with_bcs_bytes(&count)?;
10201022
let mut cached_entries_result = Vec::new();
10211023
{
10221024
let cached_entries = self.cached_entries.lock().unwrap();

linera-views/src/views/set_view.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ where
369369
#[cfg(with_metrics)]
370370
let _hash_latency = SET_VIEW_HASH_RUNTIME.measure_latency();
371371
let mut hasher = sha3::Sha3_256::default();
372-
let mut count = 0;
372+
let mut count = 0u32;
373373
self.for_each_key(|key| {
374374
count += 1;
375375
hasher.update_with_bytes(key)?;

0 commit comments

Comments
 (0)