linera_views/views/map_view.rs
1// Copyright (c) Zefchain Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4//! The `MapView` implements a map that can be modified.
5//!
6//! This reproduces more or less the functionalities of the `BTreeMap`.
7//! There are 3 different variants:
8//! * The [`ByteMapView`][class1] whose keys are the `Vec<u8>` and the values are a serializable type `V`.
9//! The ordering of the entries is via the lexicographic order of the keys.
10//! * The [`MapView`][class2] whose keys are a serializable type `K` and the value a serializable type `V`.
11//! The ordering is via the order of the BCS serialized keys.
12//! * The [`CustomMapView`][class3] whose keys are a serializable type `K` and the value a serializable type `V`.
13//! The ordering is via the order of the custom serialized keys.
14//!
15//! [class1]: map_view::ByteMapView
16//! [class2]: map_view::MapView
17//! [class3]: map_view::CustomMapView
18
19#[cfg(with_metrics)]
20use linera_base::prometheus_util::MeasureLatency as _;
21
22#[cfg(with_metrics)]
23pub(crate) mod metrics {
24 use linera_base::prometheus_util::{exponential_bucket_latencies, register_histogram_vec};
25 use prometheus::HistogramVec;
26
27 linera_base::declare_metrics! {
28 /// The runtime of hash computation
29 pub static MAP_VIEW_HASH_RUNTIME: HistogramVec =
30 register_histogram_vec(
31 "map_view_hash_runtime",
32 "MapView hash runtime",
33 &[],
34 exponential_bucket_latencies(5.0),
35 );
36 }
37}
38
39use std::{
40 borrow::{Borrow, Cow},
41 collections::{btree_map::Entry, BTreeMap},
42 marker::PhantomData,
43};
44
45use allocative::Allocative;
46use serde::{de::DeserializeOwned, Serialize};
47
48use crate::{
49 batch::Batch,
50 common::{
51 from_bytes_option, get_key_range_for_prefix, CustomSerialize, DeletionSet, HasherOutput,
52 SuffixClosedSetIterator, Update,
53 },
54 context::{BaseKey, Context},
55 hashable_wrapper::WrappedHashableContainerView,
56 historical_hash_wrapper::HistoricallyHashableView,
57 store::ReadableKeyValueStore as _,
58 views::{ClonableView, HashableView, Hasher, ReplaceContext, View, ViewError},
59};
60
61/// A view that supports inserting and removing values indexed by `Vec<u8>`.
62#[derive(Debug, Allocative)]
63#[allocative(bound = "C, V: Allocative")]
64pub struct ByteMapView<C, V> {
65 /// The view context.
66 #[allocative(skip)]
67 context: C,
68 /// Tracks deleted key prefixes.
69 deletion_set: DeletionSet,
70 /// Pending changes not yet persisted to storage.
71 updates: BTreeMap<Vec<u8>, Update<V>>,
72}
73
74impl<C: Context, C2: Context, V> ReplaceContext<C2> for ByteMapView<C, V>
75where
76 V: Send + Sync + Serialize + Clone,
77{
78 type Target = ByteMapView<C2, V>;
79
80 async fn with_context(
81 &mut self,
82 ctx: impl FnOnce(&Self::Context) -> C2 + Clone,
83 ) -> Self::Target {
84 ByteMapView {
85 context: ctx(&self.context),
86 deletion_set: self.deletion_set.clone(),
87 updates: self.updates.clone(),
88 }
89 }
90}
91
92/// Whether we have a value or its serialization.
93enum ValueOrBytes<'a, T> {
94 /// The value itself.
95 Value(&'a T),
96 /// The serialization.
97 Bytes(Vec<u8>),
98}
99
100impl<'a, T> ValueOrBytes<'a, T>
101where
102 T: Clone + DeserializeOwned,
103{
104 /// Convert to a Cow.
105 fn to_value(&self) -> Result<Cow<'a, T>, ViewError> {
106 match self {
107 ValueOrBytes::Value(value) => Ok(Cow::Borrowed(value)),
108 ValueOrBytes::Bytes(bytes) => Ok(Cow::Owned(bcs::from_bytes(bytes)?)),
109 }
110 }
111}
112
113impl<T> ValueOrBytes<'_, T>
114where
115 T: Serialize,
116{
117 /// Convert to bytes.
118 pub fn into_bytes(self) -> Result<Vec<u8>, ViewError> {
119 match self {
120 ValueOrBytes::Value(value) => Ok(bcs::to_bytes(value)?),
121 ValueOrBytes::Bytes(bytes) => Ok(bytes),
122 }
123 }
124}
125
126impl<C, V> View for ByteMapView<C, V>
127where
128 C: Context,
129 V: Send + Sync + Serialize,
130{
131 const NUM_INIT_KEYS: usize = 0;
132
133 type Context = C;
134
135 fn context(&self) -> C {
136 self.context.clone()
137 }
138
139 fn pre_load(_context: &C) -> Result<Vec<Vec<u8>>, ViewError> {
140 Ok(Vec::new())
141 }
142
143 fn post_load(context: C, _values: &[Option<Vec<u8>>]) -> Result<Self, ViewError> {
144 Ok(Self {
145 context,
146 updates: BTreeMap::new(),
147 deletion_set: DeletionSet::new(),
148 })
149 }
150
151 fn rollback(&mut self) {
152 self.updates.clear();
153 self.deletion_set.rollback();
154 }
155
156 async fn has_pending_changes(&self) -> bool {
157 self.deletion_set.has_pending_changes() || !self.updates.is_empty()
158 }
159
160 fn pre_save(&self, batch: &mut Batch) -> Result<bool, ViewError> {
161 let mut delete_view = false;
162 if self.deletion_set.delete_storage_first {
163 delete_view = true;
164 batch.delete_key_prefix(self.context.base_key().bytes.clone());
165 for (index, update) in &self.updates {
166 if let Update::Set(value) = update {
167 let key = self.context.base_key().base_index(index);
168 batch.put_key_value(key, value)?;
169 delete_view = false;
170 }
171 }
172 } else {
173 for index in &self.deletion_set.deleted_prefixes {
174 let key = self.context.base_key().base_index(index);
175 batch.delete_key_prefix(key);
176 }
177 for (index, update) in &self.updates {
178 let key = self.context.base_key().base_index(index);
179 match update {
180 Update::Removed => batch.delete_key(key),
181 Update::Set(value) => batch.put_key_value(key, value)?,
182 }
183 }
184 }
185 Ok(delete_view)
186 }
187
188 fn post_save(&mut self) {
189 self.updates.clear();
190 self.deletion_set.delete_storage_first = false;
191 self.deletion_set.deleted_prefixes.clear();
192 }
193
194 fn clear(&mut self) {
195 self.updates.clear();
196 self.deletion_set.clear();
197 }
198}
199
200impl<C: Clone, V: Clone> ClonableView for ByteMapView<C, V>
201where
202 Self: View,
203{
204 fn clone_unchecked(&mut self) -> Result<Self, ViewError> {
205 Ok(ByteMapView {
206 context: self.context.clone(),
207 updates: self.updates.clone(),
208 deletion_set: self.deletion_set.clone(),
209 })
210 }
211}
212
213impl<C, V> ByteMapView<C, V>
214where
215 C: Context,
216{
217 /// Inserts or resets the value of a key of the map.
218 /// ```rust
219 /// # tokio_test::block_on(async {
220 /// # use linera_views::context::MemoryContext;
221 /// # use linera_views::map_view::ByteMapView;
222 /// # use linera_views::views::View;
223 /// # let context = MemoryContext::new_for_testing(());
224 /// let mut map = ByteMapView::load(context).await.unwrap();
225 /// map.insert(vec![0, 1], String::from("Hello"));
226 /// assert_eq!(map.keys().await.unwrap(), vec![vec![0, 1]]);
227 /// # })
228 /// ```
229 pub fn insert(&mut self, short_key: Vec<u8>, value: V) {
230 self.updates.insert(short_key, Update::Set(value));
231 }
232
233 /// Removes a value. If absent then nothing is done.
234 /// ```rust
235 /// # tokio_test::block_on(async {
236 /// # use linera_views::context::MemoryContext;
237 /// # use linera_views::map_view::ByteMapView;
238 /// # use linera_views::views::View;
239 /// # let context = MemoryContext::new_for_testing(());
240 /// let mut map = ByteMapView::load(context).await.unwrap();
241 /// map.insert(vec![0, 1], "Hello");
242 /// map.remove(vec![0, 1]);
243 /// # })
244 /// ```
245 pub fn remove(&mut self, short_key: Vec<u8>) {
246 if self.deletion_set.contains_prefix_of(&short_key) {
247 // Optimization: No need to mark `short_key` for deletion as we are going to remove a range of keys containing it.
248 self.updates.remove(&short_key);
249 } else {
250 self.updates.insert(short_key, Update::Removed);
251 }
252 }
253
254 /// Removes a value. If absent then nothing is done.
255 /// ```rust
256 /// # tokio_test::block_on(async {
257 /// # use linera_views::context::MemoryContext;
258 /// # use linera_views::map_view::ByteMapView;
259 /// # use linera_views::views::View;
260 /// # let context = MemoryContext::new_for_testing(());
261 /// let mut map = ByteMapView::load(context).await.unwrap();
262 /// map.insert(vec![0, 1], String::from("Hello"));
263 /// map.insert(vec![0, 2], String::from("Bonjour"));
264 /// map.remove_by_prefix(vec![0]);
265 /// assert!(map.keys().await.unwrap().is_empty());
266 /// # })
267 /// ```
268 pub fn remove_by_prefix(&mut self, key_prefix: Vec<u8>) {
269 let key_list = self
270 .updates
271 .range(get_key_range_for_prefix(key_prefix.clone()))
272 .map(|x| x.0.to_vec())
273 .collect::<Vec<_>>();
274 for key in key_list {
275 self.updates.remove(&key);
276 }
277 self.deletion_set.insert_key_prefix(key_prefix);
278 }
279
280 /// Obtains the extra data.
281 pub fn extra(&self) -> &C::Extra {
282 self.context.extra()
283 }
284
285 /// Returns `true` if the map contains a value for the specified key.
286 /// ```rust
287 /// # tokio_test::block_on(async {
288 /// # use linera_views::context::MemoryContext;
289 /// # use linera_views::map_view::ByteMapView;
290 /// # use linera_views::views::View;
291 /// # let context = MemoryContext::new_for_testing(());
292 /// let mut map = ByteMapView::load(context).await.unwrap();
293 /// map.insert(vec![0, 1], String::from("Hello"));
294 /// assert!(map.contains_key(&[0, 1]).await.unwrap());
295 /// assert!(!map.contains_key(&[0, 2]).await.unwrap());
296 /// # })
297 /// ```
298 pub async fn contains_key(&self, short_key: &[u8]) -> Result<bool, ViewError> {
299 if let Some(update) = self.updates.get(short_key) {
300 let test = match update {
301 Update::Removed => false,
302 Update::Set(_value) => true,
303 };
304 return Ok(test);
305 }
306 if self.deletion_set.contains_prefix_of(short_key) {
307 return Ok(false);
308 }
309 let key = self.context.base_key().base_index(short_key);
310 Ok(self.context.store().contains_key(&key).await?)
311 }
312}
313
314impl<C, V> ByteMapView<C, V>
315where
316 C: Context,
317 V: Clone + DeserializeOwned + 'static,
318{
319 /// Reads the value at the given position, if any.
320 /// ```rust
321 /// # tokio_test::block_on(async {
322 /// # use linera_views::context::MemoryContext;
323 /// # use linera_views::map_view::ByteMapView;
324 /// # use linera_views::views::View;
325 /// # let context = MemoryContext::new_for_testing(());
326 /// let mut map = ByteMapView::load(context).await.unwrap();
327 /// map.insert(vec![0, 1], String::from("Hello"));
328 /// assert_eq!(map.get(&[0, 1]).await.unwrap(), Some(String::from("Hello")));
329 /// # })
330 /// ```
331 pub async fn get(&self, short_key: &[u8]) -> Result<Option<V>, ViewError> {
332 if let Some(update) = self.updates.get(short_key) {
333 let value = match update {
334 Update::Removed => None,
335 Update::Set(value) => Some(value.clone()),
336 };
337 return Ok(value);
338 }
339 if self.deletion_set.contains_prefix_of(short_key) {
340 return Ok(None);
341 }
342 let key = self.context.base_key().base_index(short_key);
343 Ok(self.context.store().read_value(&key).await?)
344 }
345
346 /// Reads the values at the given positions, if any.
347 /// ```rust
348 /// # tokio_test::block_on(async {
349 /// # use linera_views::context::MemoryContext;
350 /// # use linera_views::map_view::ByteMapView;
351 /// # use linera_views::views::View;
352 /// # let context = MemoryContext::new_for_testing(());
353 /// let mut map = ByteMapView::load(context).await.unwrap();
354 /// map.insert(vec![0, 1], String::from("Hello"));
355 /// let values = map.multi_get(vec![vec![0, 1], vec![0, 2]]).await.unwrap();
356 /// assert_eq!(values, vec![Some(String::from("Hello")), None]);
357 /// # })
358 /// ```
359 pub async fn multi_get(&self, short_keys: Vec<Vec<u8>>) -> Result<Vec<Option<V>>, ViewError> {
360 let size = short_keys.len();
361 let mut results = vec![None; size];
362 let mut missed_indices = Vec::new();
363 let mut vector_query = Vec::new();
364 for (i, short_key) in short_keys.into_iter().enumerate() {
365 if let Some(update) = self.updates.get(&short_key) {
366 if let Update::Set(value) = update {
367 results[i] = Some(value.clone());
368 }
369 } else if !self.deletion_set.contains_prefix_of(&short_key) {
370 missed_indices.push(i);
371 let key = self.context.base_key().base_index(&short_key);
372 vector_query.push(key);
373 }
374 }
375 let values = self
376 .context
377 .store()
378 .read_multi_values_bytes(&vector_query)
379 .await?;
380 for (i, value) in missed_indices.into_iter().zip(values) {
381 results[i] = from_bytes_option(&value)?;
382 }
383 Ok(results)
384 }
385
386 /// Reads the key-value pairs at the given positions, if any.
387 /// ```rust
388 /// # tokio_test::block_on(async {
389 /// # use linera_views::context::MemoryContext;
390 /// # use linera_views::map_view::ByteMapView;
391 /// # use linera_views::views::View;
392 /// # let context = MemoryContext::new_for_testing(());
393 /// let mut map = ByteMapView::load(context).await.unwrap();
394 /// map.insert(vec![0, 1], String::from("Hello"));
395 /// let pairs = map
396 /// .multi_get_pairs(vec![vec![0, 1], vec![0, 2]])
397 /// .await
398 /// .unwrap();
399 /// assert_eq!(
400 /// pairs,
401 /// vec![
402 /// (vec![0, 1], Some(String::from("Hello"))),
403 /// (vec![0, 2], None)
404 /// ]
405 /// );
406 /// # })
407 /// ```
408 pub async fn multi_get_pairs(
409 &self,
410 short_keys: Vec<Vec<u8>>,
411 ) -> Result<Vec<(Vec<u8>, Option<V>)>, ViewError> {
412 let values = self.multi_get(short_keys.clone()).await?;
413 Ok(short_keys.into_iter().zip(values).collect())
414 }
415
416 /// Obtains a mutable reference to a value at a given position if available.
417 /// ```rust
418 /// # tokio_test::block_on(async {
419 /// # use linera_views::context::MemoryContext;
420 /// # use linera_views::map_view::ByteMapView;
421 /// # use linera_views::views::View;
422 /// # let context = MemoryContext::new_for_testing(());
423 /// let mut map = ByteMapView::load(context).await.unwrap();
424 /// map.insert(vec![0, 1], String::from("Hello"));
425 /// let value = map.get_mut(&[0, 1]).await.unwrap().unwrap();
426 /// assert_eq!(*value, String::from("Hello"));
427 /// *value = String::from("Hola");
428 /// assert_eq!(map.get(&[0, 1]).await.unwrap(), Some(String::from("Hola")));
429 /// # })
430 /// ```
431 pub async fn get_mut(&mut self, short_key: &[u8]) -> Result<Option<&mut V>, ViewError> {
432 let update = match self.updates.entry(short_key.to_vec()) {
433 Entry::Vacant(e) => {
434 if self.deletion_set.contains_prefix_of(short_key) {
435 None
436 } else {
437 let key = self.context.base_key().base_index(short_key);
438 let value = self.context.store().read_value(&key).await?;
439 value.map(|value| e.insert(Update::Set(value)))
440 }
441 }
442 Entry::Occupied(e) => Some(e.into_mut()),
443 };
444 Ok(match update {
445 Some(Update::Set(value)) => Some(value),
446 _ => None,
447 })
448 }
449}
450
451impl<C, V> ByteMapView<C, V>
452where
453 C: Context,
454 V: Clone + Serialize + DeserializeOwned + 'static,
455{
456 /// Applies the function f on each index (aka key) which has the assigned prefix.
457 /// Keys are visited in the lexicographic order. The shortened key is send to the
458 /// function and if it returns false, then the loop exits
459 /// ```rust
460 /// # tokio_test::block_on(async {
461 /// # use linera_views::context::MemoryContext;
462 /// # use linera_views::map_view::ByteMapView;
463 /// # use linera_views::views::View;
464 /// # let context = MemoryContext::new_for_testing(());
465 /// let mut map = ByteMapView::load(context).await.unwrap();
466 /// map.insert(vec![0, 1], String::from("Hello"));
467 /// map.insert(vec![1, 2], String::from("Bonjour"));
468 /// map.insert(vec![1, 3], String::from("Bonjour"));
469 /// let prefix = vec![1];
470 /// let mut count = 0;
471 /// map.for_each_key_while(
472 /// |_key| {
473 /// count += 1;
474 /// Ok(count < 3)
475 /// },
476 /// prefix,
477 /// )
478 /// .await
479 /// .unwrap();
480 /// assert_eq!(count, 2);
481 /// # })
482 /// ```
483 pub async fn for_each_key_while<F>(&self, mut f: F, prefix: Vec<u8>) -> Result<(), ViewError>
484 where
485 F: FnMut(&[u8]) -> Result<bool, ViewError> + Send,
486 {
487 let prefix_len = prefix.len();
488 let mut updates = self.updates.range(get_key_range_for_prefix(prefix.clone()));
489 let mut update = updates.next();
490 if !self.deletion_set.contains_prefix_of(&prefix) {
491 let iter = self
492 .deletion_set
493 .deleted_prefixes
494 .range(get_key_range_for_prefix(prefix.clone()));
495 let mut suffix_closed_set = SuffixClosedSetIterator::new(prefix_len, iter);
496 let base = self.context.base_key().base_index(&prefix);
497 for index in self.context.store().find_keys_by_prefix(&base).await? {
498 loop {
499 match update {
500 Some((key, value)) if &key[prefix_len..] <= index.as_slice() => {
501 if let Update::Set(_) = value {
502 if !f(&key[prefix_len..])? {
503 return Ok(());
504 }
505 }
506 update = updates.next();
507 if key[prefix_len..] == index {
508 break;
509 }
510 }
511 _ => {
512 if !suffix_closed_set.find_key(&index) && !f(&index)? {
513 return Ok(());
514 }
515 break;
516 }
517 }
518 }
519 }
520 }
521 while let Some((key, value)) = update {
522 if let Update::Set(_) = value {
523 if !f(&key[prefix_len..])? {
524 return Ok(());
525 }
526 }
527 update = updates.next();
528 }
529 Ok(())
530 }
531
532 /// Applies the function f on each index (aka key) having the specified prefix.
533 /// The shortened keys are sent to the function f. Keys are visited in the
534 /// lexicographic order.
535 /// ```rust
536 /// # tokio_test::block_on(async {
537 /// # use linera_views::context::MemoryContext;
538 /// # use linera_views::map_view::ByteMapView;
539 /// # use linera_views::views::View;
540 /// # let context = MemoryContext::new_for_testing(());
541 /// let mut map = ByteMapView::load(context).await.unwrap();
542 /// map.insert(vec![0, 1], String::from("Hello"));
543 /// let mut count = 0;
544 /// let prefix = Vec::new();
545 /// map.for_each_key(
546 /// |_key| {
547 /// count += 1;
548 /// Ok(())
549 /// },
550 /// prefix,
551 /// )
552 /// .await
553 /// .unwrap();
554 /// assert_eq!(count, 1);
555 /// # })
556 /// ```
557 pub async fn for_each_key<F>(&self, mut f: F, prefix: Vec<u8>) -> Result<(), ViewError>
558 where
559 F: FnMut(&[u8]) -> Result<(), ViewError> + Send,
560 {
561 self.for_each_key_while(
562 |key| {
563 f(key)?;
564 Ok(true)
565 },
566 prefix,
567 )
568 .await
569 }
570
571 /// Returns the list of keys of the map in lexicographic order.
572 /// ```rust
573 /// # tokio_test::block_on(async {
574 /// # use linera_views::context::MemoryContext;
575 /// # use linera_views::map_view::ByteMapView;
576 /// # use linera_views::views::View;
577 /// # let context = MemoryContext::new_for_testing(());
578 /// let mut map = ByteMapView::load(context).await.unwrap();
579 /// map.insert(vec![0, 1], String::from("Hello"));
580 /// map.insert(vec![1, 2], String::from("Bonjour"));
581 /// map.insert(vec![2, 2], String::from("Hallo"));
582 /// assert_eq!(
583 /// map.keys().await.unwrap(),
584 /// vec![vec![0, 1], vec![1, 2], vec![2, 2]]
585 /// );
586 /// # })
587 /// ```
588 pub async fn keys(&self) -> Result<Vec<Vec<u8>>, ViewError> {
589 let mut keys = Vec::new();
590 let prefix = Vec::new();
591 self.for_each_key(
592 |key| {
593 keys.push(key.to_vec());
594 Ok(())
595 },
596 prefix,
597 )
598 .await?;
599 Ok(keys)
600 }
601
602 /// Returns the list of keys of the map having a specified prefix
603 /// in lexicographic order.
604 /// ```rust
605 /// # tokio_test::block_on(async {
606 /// # use linera_views::context::MemoryContext;
607 /// # use linera_views::map_view::ByteMapView;
608 /// # use linera_views::views::View;
609 /// # let context = MemoryContext::new_for_testing(());
610 /// let mut map = ByteMapView::load(context).await.unwrap();
611 /// map.insert(vec![0, 1], String::from("Hello"));
612 /// map.insert(vec![1, 2], String::from("Bonjour"));
613 /// map.insert(vec![1, 3], String::from("Hallo"));
614 /// assert_eq!(
615 /// map.keys_by_prefix(vec![1]).await.unwrap(),
616 /// vec![vec![1, 2], vec![1, 3]]
617 /// );
618 /// # })
619 /// ```
620 pub async fn keys_by_prefix(&self, prefix: Vec<u8>) -> Result<Vec<Vec<u8>>, ViewError> {
621 let mut keys = Vec::new();
622 let prefix_clone = prefix.clone();
623 self.for_each_key(
624 |key| {
625 let mut big_key = prefix.clone();
626 big_key.extend(key);
627 keys.push(big_key);
628 Ok(())
629 },
630 prefix_clone,
631 )
632 .await?;
633 Ok(keys)
634 }
635
636 /// Returns the number of keys of the map
637 /// ```rust
638 /// # tokio_test::block_on(async {
639 /// # use linera_views::context::MemoryContext;
640 /// # use linera_views::map_view::ByteMapView;
641 /// # use linera_views::views::View;
642 /// # let context = MemoryContext::new_for_testing(());
643 /// let mut map = ByteMapView::load(context).await.unwrap();
644 /// map.insert(vec![0, 1], String::from("Hello"));
645 /// map.insert(vec![1, 2], String::from("Bonjour"));
646 /// map.insert(vec![2, 2], String::from("Hallo"));
647 /// assert_eq!(map.iterative_count().await.unwrap(), 3);
648 /// # })
649 /// ```
650 pub async fn iterative_count(&self) -> Result<usize, ViewError> {
651 let mut count = 0;
652 let prefix = Vec::new();
653 self.for_each_key(
654 |_key| {
655 count += 1;
656 Ok(())
657 },
658 prefix,
659 )
660 .await?;
661 Ok(count)
662 }
663
664 /// Applies a function f on each key/value pair matching a prefix. The key is the
665 /// shortened one by the prefix. The value is an enum that can be either a value
666 /// or its serialization. This is needed in order to avoid a scenario where we
667 /// deserialize something that was serialized. The key/value are send to the
668 /// function f. If it returns false the loop ends prematurely. Keys and values
669 /// are visited in the lexicographic order.
670 async fn for_each_key_value_or_bytes_while<'a, F>(
671 &'a self,
672 mut f: F,
673 prefix: Vec<u8>,
674 ) -> Result<(), ViewError>
675 where
676 F: FnMut(&[u8], ValueOrBytes<'a, V>) -> Result<bool, ViewError> + Send,
677 {
678 let prefix_len = prefix.len();
679 let mut updates = self.updates.range(get_key_range_for_prefix(prefix.clone()));
680 let mut update = updates.next();
681 if !self.deletion_set.contains_prefix_of(&prefix) {
682 let iter = self
683 .deletion_set
684 .deleted_prefixes
685 .range(get_key_range_for_prefix(prefix.clone()));
686 let mut suffix_closed_set = SuffixClosedSetIterator::new(prefix_len, iter);
687 let base = self.context.base_key().base_index(&prefix);
688 for (index, bytes) in self
689 .context
690 .store()
691 .find_key_values_by_prefix(&base)
692 .await?
693 {
694 loop {
695 match update {
696 Some((key, value)) if key[prefix_len..] <= *index => {
697 if let Update::Set(value) = value {
698 let value = ValueOrBytes::Value(value);
699 if !f(&key[prefix_len..], value)? {
700 return Ok(());
701 }
702 }
703 update = updates.next();
704 if key[prefix_len..] == index {
705 break;
706 }
707 }
708 _ => {
709 if !suffix_closed_set.find_key(&index) {
710 let value = ValueOrBytes::Bytes(bytes);
711 if !f(&index, value)? {
712 return Ok(());
713 }
714 }
715 break;
716 }
717 }
718 }
719 }
720 }
721 while let Some((key, value)) = update {
722 if let Update::Set(value) = value {
723 let value = ValueOrBytes::Value(value);
724 if !f(&key[prefix_len..], value)? {
725 return Ok(());
726 }
727 }
728 update = updates.next();
729 }
730 Ok(())
731 }
732 /// Applies a function f on each index/value pair matching a prefix. Keys
733 /// and values are visited in the lexicographic order. The shortened index
734 /// is send to the function f and if it returns false then the loop ends
735 /// prematurely
736 /// ```rust
737 /// # tokio_test::block_on(async {
738 /// # use linera_views::context::MemoryContext;
739 /// # use linera_views::map_view::ByteMapView;
740 /// # use linera_views::views::View;
741 /// # let context = MemoryContext::new_for_testing(());
742 /// let mut map = ByteMapView::load(context).await.unwrap();
743 /// map.insert(vec![0, 1], String::from("Hello"));
744 /// map.insert(vec![1, 2], String::from("Bonjour"));
745 /// map.insert(vec![1, 3], String::from("Hallo"));
746 /// let mut part_keys = Vec::new();
747 /// let prefix = vec![1];
748 /// map.for_each_key_value_while(
749 /// |key, _value| {
750 /// part_keys.push(key.to_vec());
751 /// Ok(part_keys.len() < 2)
752 /// },
753 /// prefix,
754 /// )
755 /// .await
756 /// .unwrap();
757 /// assert_eq!(part_keys.len(), 2);
758 /// # })
759 /// ```
760 pub async fn for_each_key_value_while<'a, F>(
761 &'a self,
762 mut f: F,
763 prefix: Vec<u8>,
764 ) -> Result<(), ViewError>
765 where
766 F: FnMut(&[u8], Cow<'a, V>) -> Result<bool, ViewError> + Send,
767 {
768 self.for_each_key_value_or_bytes_while(
769 |key, value| {
770 let value = value.to_value()?;
771 f(key, value)
772 },
773 prefix,
774 )
775 .await
776 }
777
778 /// Applies a function f on each key/value pair matching a prefix. The key is the
779 /// shortened one by the prefix. The value is an enum that can be either a value
780 /// or its serialization. This is needed in order to avoid a scenario where we
781 /// deserialize something that was serialized. The key/value are send to the
782 /// function f. Keys and values are visited in the lexicographic order.
783 async fn for_each_key_value_or_bytes<'a, F>(
784 &'a self,
785 mut f: F,
786 prefix: Vec<u8>,
787 ) -> Result<(), ViewError>
788 where
789 F: FnMut(&[u8], ValueOrBytes<'a, V>) -> Result<(), ViewError> + Send,
790 {
791 self.for_each_key_value_or_bytes_while(
792 |key, value| {
793 f(key, value)?;
794 Ok(true)
795 },
796 prefix,
797 )
798 .await
799 }
800
801 /// Applies a function f on each key/value pair matching a prefix. The shortened
802 /// key and value are send to the function f. Keys and values are visited in the
803 /// lexicographic order.
804 /// ```rust
805 /// # tokio_test::block_on(async {
806 /// # use linera_views::context::MemoryContext;
807 /// # use linera_views::map_view::ByteMapView;
808 /// # use linera_views::views::View;
809 /// # let context = MemoryContext::new_for_testing(());
810 /// let mut map = ByteMapView::load(context).await.unwrap();
811 /// map.insert(vec![0, 1], String::from("Hello"));
812 /// let mut count = 0;
813 /// let prefix = Vec::new();
814 /// map.for_each_key_value(
815 /// |_key, _value| {
816 /// count += 1;
817 /// Ok(())
818 /// },
819 /// prefix,
820 /// )
821 /// .await
822 /// .unwrap();
823 /// assert_eq!(count, 1);
824 /// # })
825 /// ```
826 pub async fn for_each_key_value<'a, F>(
827 &'a self,
828 mut f: F,
829 prefix: Vec<u8>,
830 ) -> Result<(), ViewError>
831 where
832 F: FnMut(&[u8], Cow<'a, V>) -> Result<(), ViewError> + Send,
833 {
834 self.for_each_key_value_while(
835 |key, value| {
836 f(key, value)?;
837 Ok(true)
838 },
839 prefix,
840 )
841 .await
842 }
843}
844
845impl<C, V> ByteMapView<C, V>
846where
847 C: Context,
848 V: Clone + Send + Serialize + DeserializeOwned + 'static,
849{
850 /// Returns the list of keys and values of the map matching a prefix
851 /// in lexicographic order.
852 /// ```rust
853 /// # tokio_test::block_on(async {
854 /// # use linera_views::context::MemoryContext;
855 /// # use linera_views::map_view::ByteMapView;
856 /// # use linera_views::views::View;
857 /// # let context = MemoryContext::new_for_testing(());
858 /// let mut map = ByteMapView::load(context).await.unwrap();
859 /// map.insert(vec![1, 2], String::from("Hello"));
860 /// let prefix = vec![1];
861 /// assert_eq!(
862 /// map.key_values_by_prefix(prefix).await.unwrap(),
863 /// vec![(vec![1, 2], String::from("Hello"))]
864 /// );
865 /// # })
866 /// ```
867 pub async fn key_values_by_prefix(
868 &self,
869 prefix: Vec<u8>,
870 ) -> Result<Vec<(Vec<u8>, V)>, ViewError> {
871 let mut key_values = Vec::new();
872 let prefix_copy = prefix.clone();
873 self.for_each_key_value(
874 |key, value| {
875 let mut big_key = prefix.clone();
876 big_key.extend(key);
877 let value = value.into_owned();
878 key_values.push((big_key, value));
879 Ok(())
880 },
881 prefix_copy,
882 )
883 .await?;
884 Ok(key_values)
885 }
886
887 /// Returns the list of keys and values of the map in lexicographic order.
888 /// ```rust
889 /// # tokio_test::block_on(async {
890 /// # use linera_views::context::MemoryContext;
891 /// # use linera_views::map_view::ByteMapView;
892 /// # use linera_views::views::View;
893 /// # let context = MemoryContext::new_for_testing(());
894 /// let mut map = ByteMapView::load(context).await.unwrap();
895 /// map.insert(vec![1, 2], String::from("Hello"));
896 /// assert_eq!(
897 /// map.key_values().await.unwrap(),
898 /// vec![(vec![1, 2], String::from("Hello"))]
899 /// );
900 /// # })
901 /// ```
902 pub async fn key_values(&self) -> Result<Vec<(Vec<u8>, V)>, ViewError> {
903 self.key_values_by_prefix(Vec::new()).await
904 }
905}
906
907impl<C, V> ByteMapView<C, V>
908where
909 C: Context,
910 V: Default + DeserializeOwned + 'static,
911{
912 /// Obtains a mutable reference to a value at a given position.
913 /// Default value if the index is missing.
914 /// ```rust
915 /// # tokio_test::block_on(async {
916 /// # use linera_views::context::MemoryContext;
917 /// # use linera_views::map_view::ByteMapView;
918 /// # use linera_views::views::View;
919 /// # let context = MemoryContext::new_for_testing(());
920 /// let mut map = ByteMapView::load(context).await.unwrap();
921 /// map.insert(vec![0, 1], String::from("Hello"));
922 /// assert_eq!(map.get_mut_or_default(&[7]).await.unwrap(), "");
923 /// let value = map.get_mut_or_default(&[0, 1]).await.unwrap();
924 /// assert_eq!(*value, String::from("Hello"));
925 /// *value = String::from("Hola");
926 /// assert_eq!(map.get(&[0, 1]).await.unwrap(), Some(String::from("Hola")));
927 /// # })
928 /// ```
929 pub async fn get_mut_or_default(&mut self, short_key: &[u8]) -> Result<&mut V, ViewError> {
930 let update = match self.updates.entry(short_key.to_vec()) {
931 Entry::Vacant(e) if self.deletion_set.contains_prefix_of(short_key) => {
932 e.insert(Update::Set(V::default()))
933 }
934 Entry::Vacant(e) => {
935 let key = self.context.base_key().base_index(short_key);
936 let value = self
937 .context
938 .store()
939 .read_value(&key)
940 .await?
941 .unwrap_or_default();
942 e.insert(Update::Set(value))
943 }
944 Entry::Occupied(entry) => {
945 let entry = entry.into_mut();
946 match entry {
947 Update::Set(_) => &mut *entry,
948 Update::Removed => {
949 *entry = Update::Set(V::default());
950 &mut *entry
951 }
952 }
953 }
954 };
955 let Update::Set(value) = update else {
956 unreachable!("ByteMapView::get_mut_or_default: update entry is Update::Removed but every match arm above must insert Update::Set")
957 };
958 Ok(value)
959 }
960}
961
962impl<C, V> HashableView for ByteMapView<C, V>
963where
964 C: Context,
965 V: Clone + Send + Sync + Serialize + DeserializeOwned + 'static,
966{
967 type Hasher = sha3::Sha3_256;
968
969 async fn hash_mut(&mut self) -> Result<<Self::Hasher as Hasher>::Output, ViewError> {
970 self.hash().await
971 }
972
973 async fn hash(&self) -> Result<<Self::Hasher as Hasher>::Output, ViewError> {
974 #[cfg(with_metrics)]
975 let _hash_latency = metrics::MAP_VIEW_HASH_RUNTIME.measure_latency();
976 let mut hasher = sha3::Sha3_256::default();
977 let mut count = 0u32;
978 let prefix = Vec::new();
979 self.for_each_key_value_or_bytes(
980 |index, value| {
981 count += 1;
982 hasher.update_with_bytes(index)?;
983 let bytes = value.into_bytes()?;
984 hasher.update_with_bytes(&bytes)?;
985 Ok(())
986 },
987 prefix,
988 )
989 .await?;
990 hasher.update_with_bcs_bytes(&count)?;
991 Ok(hasher.finalize())
992 }
993}
994
995/// A `View` that has a type for keys. The ordering of the entries
996/// is determined by the serialization of the context.
997#[derive(Debug, Allocative)]
998#[allocative(bound = "C, I, V: Allocative")]
999pub struct MapView<C, I, V> {
1000 /// The underlying map storing entries with serialized keys.
1001 map: ByteMapView<C, V>,
1002 /// Phantom data for the key type.
1003 #[allocative(skip)]
1004 _phantom: PhantomData<I>,
1005}
1006
1007impl<C, C2, I, V> ReplaceContext<C2> for MapView<C, I, V>
1008where
1009 C: Context,
1010 C2: Context,
1011 I: Send + Sync,
1012 V: Send + Sync + Serialize + Clone,
1013{
1014 type Target = MapView<C2, I, V>;
1015
1016 async fn with_context(
1017 &mut self,
1018 ctx: impl FnOnce(&Self::Context) -> C2 + Clone,
1019 ) -> Self::Target {
1020 MapView {
1021 map: self.map.with_context(ctx).await,
1022 _phantom: self._phantom,
1023 }
1024 }
1025}
1026
1027impl<C, I, V> View for MapView<C, I, V>
1028where
1029 C: Context,
1030 I: Send + Sync,
1031 V: Send + Sync + Serialize,
1032{
1033 const NUM_INIT_KEYS: usize = ByteMapView::<C, V>::NUM_INIT_KEYS;
1034
1035 type Context = C;
1036
1037 fn context(&self) -> C {
1038 self.map.context()
1039 }
1040
1041 fn pre_load(context: &C) -> Result<Vec<Vec<u8>>, ViewError> {
1042 ByteMapView::<C, V>::pre_load(context)
1043 }
1044
1045 fn post_load(context: C, values: &[Option<Vec<u8>>]) -> Result<Self, ViewError> {
1046 let map = ByteMapView::post_load(context, values)?;
1047 Ok(MapView {
1048 map,
1049 _phantom: PhantomData,
1050 })
1051 }
1052
1053 fn rollback(&mut self) {
1054 self.map.rollback()
1055 }
1056
1057 async fn has_pending_changes(&self) -> bool {
1058 self.map.has_pending_changes().await
1059 }
1060
1061 fn pre_save(&self, batch: &mut Batch) -> Result<bool, ViewError> {
1062 self.map.pre_save(batch)
1063 }
1064
1065 fn post_save(&mut self) {
1066 self.map.post_save()
1067 }
1068
1069 fn clear(&mut self) {
1070 self.map.clear()
1071 }
1072}
1073
1074impl<C, I, V: Clone> ClonableView for MapView<C, I, V>
1075where
1076 Self: View,
1077 ByteMapView<C, V>: ClonableView,
1078{
1079 fn clone_unchecked(&mut self) -> Result<Self, ViewError> {
1080 Ok(MapView {
1081 map: self.map.clone_unchecked()?,
1082 _phantom: PhantomData,
1083 })
1084 }
1085}
1086
1087impl<C, I, V> MapView<C, I, V>
1088where
1089 C: Context,
1090 I: Serialize,
1091{
1092 /// Inserts or resets a value at an index.
1093 /// ```rust
1094 /// # tokio_test::block_on(async {
1095 /// # use linera_views::context::MemoryContext;
1096 /// # use linera_views::map_view::MapView;
1097 /// # use linera_views::views::View;
1098 /// # let context = MemoryContext::new_for_testing(());
1099 /// let mut map: MapView<_, u32, _> = MapView::load(context).await.unwrap();
1100 /// map.insert(&(24 as u32), String::from("Hello"));
1101 /// assert_eq!(
1102 /// map.get(&(24 as u32)).await.unwrap(),
1103 /// Some(String::from("Hello"))
1104 /// );
1105 /// # })
1106 /// ```
1107 pub fn insert<Q>(&mut self, index: &Q, value: V) -> Result<(), ViewError>
1108 where
1109 I: Borrow<Q>,
1110 Q: Serialize + ?Sized,
1111 {
1112 let short_key = BaseKey::derive_short_key(index)?;
1113 self.map.insert(short_key, value);
1114 Ok(())
1115 }
1116
1117 /// Removes a value. If absent then the operation does nothing.
1118 /// ```rust
1119 /// # tokio_test::block_on(async {
1120 /// # use linera_views::context::MemoryContext;
1121 /// # use linera_views::map_view::MapView;
1122 /// # use linera_views::views::View;
1123 /// # let context = MemoryContext::new_for_testing(());
1124 /// let mut map = MapView::<_, u32, String>::load(context).await.unwrap();
1125 /// map.remove(&(37 as u32));
1126 /// assert_eq!(map.get(&(37 as u32)).await.unwrap(), None);
1127 /// # })
1128 /// ```
1129 pub fn remove<Q>(&mut self, index: &Q) -> Result<(), ViewError>
1130 where
1131 I: Borrow<Q>,
1132 Q: Serialize + ?Sized,
1133 {
1134 let short_key = BaseKey::derive_short_key(index)?;
1135 self.map.remove(short_key);
1136 Ok(())
1137 }
1138
1139 /// Obtains the extra data.
1140 pub fn extra(&self) -> &C::Extra {
1141 self.map.extra()
1142 }
1143
1144 /// Returns `true` if the map contains a value for the specified key.
1145 /// ```rust
1146 /// # tokio_test::block_on(async {
1147 /// # use linera_views::context::MemoryContext;
1148 /// # use linera_views::map_view::MapView;
1149 /// # use linera_views::views::View;
1150 /// # let context = MemoryContext::new_for_testing(());
1151 /// let mut map = MapView::<_, u32, String>::load(context).await.unwrap();
1152 /// map.insert(&(37 as u32), String::from("Hello"));
1153 /// assert!(map.contains_key(&(37 as u32)).await.unwrap());
1154 /// assert!(!map.contains_key(&(34 as u32)).await.unwrap());
1155 /// # })
1156 /// ```
1157 pub async fn contains_key<Q>(&self, index: &Q) -> Result<bool, ViewError>
1158 where
1159 I: Borrow<Q>,
1160 Q: Serialize + ?Sized,
1161 {
1162 let short_key = BaseKey::derive_short_key(index)?;
1163 self.map.contains_key(&short_key).await
1164 }
1165}
1166
1167impl<C, I, V> MapView<C, I, V>
1168where
1169 C: Context,
1170 I: Serialize,
1171 V: Clone + DeserializeOwned + 'static,
1172{
1173 /// Reads the value at the given position, if any.
1174 /// ```rust
1175 /// # tokio_test::block_on(async {
1176 /// # use linera_views::context::MemoryContext;
1177 /// # use linera_views::map_view::MapView;
1178 /// # use linera_views::views::View;
1179 /// # let context = MemoryContext::new_for_testing(());
1180 /// let mut map: MapView<_, u32, _> = MapView::load(context).await.unwrap();
1181 /// map.insert(&(37 as u32), String::from("Hello"));
1182 /// assert_eq!(
1183 /// map.get(&(37 as u32)).await.unwrap(),
1184 /// Some(String::from("Hello"))
1185 /// );
1186 /// assert_eq!(map.get(&(34 as u32)).await.unwrap(), None);
1187 /// # })
1188 /// ```
1189 pub async fn get<Q>(&self, index: &Q) -> Result<Option<V>, ViewError>
1190 where
1191 I: Borrow<Q>,
1192 Q: Serialize + ?Sized,
1193 {
1194 let short_key = BaseKey::derive_short_key(index)?;
1195 self.map.get(&short_key).await
1196 }
1197
1198 /// Reads values at given positions, if any.
1199 /// ```rust
1200 /// # tokio_test::block_on(async {
1201 /// # use linera_views::context::MemoryContext;
1202 /// # use linera_views::map_view::MapView;
1203 /// # use linera_views::views::View;
1204 /// # let context = MemoryContext::new_for_testing(());
1205 /// let mut map: MapView<_, u32, _> = MapView::load(context).await.unwrap();
1206 /// map.insert(&(37 as u32), String::from("Hello"));
1207 /// map.insert(&(49 as u32), String::from("Bonjour"));
1208 /// assert_eq!(
1209 /// map.multi_get(&[37 as u32, 49 as u32, 64 as u32])
1210 /// .await
1211 /// .unwrap(),
1212 /// [
1213 /// Some(String::from("Hello")),
1214 /// Some(String::from("Bonjour")),
1215 /// None
1216 /// ]
1217 /// );
1218 /// assert_eq!(map.get(&(34 as u32)).await.unwrap(), None);
1219 /// # })
1220 /// ```
1221 pub async fn multi_get<'a, Q>(
1222 &self,
1223 indices: impl IntoIterator<Item = &'a Q>,
1224 ) -> Result<Vec<Option<V>>, ViewError>
1225 where
1226 I: Borrow<Q>,
1227 Q: Serialize + 'a,
1228 {
1229 let short_keys = indices
1230 .into_iter()
1231 .map(|index| BaseKey::derive_short_key(index))
1232 .collect::<Result<_, _>>()?;
1233 self.map.multi_get(short_keys).await
1234 }
1235
1236 /// Reads the index-value pairs at the given positions, if any.
1237 /// ```rust
1238 /// # tokio_test::block_on(async {
1239 /// # use linera_views::context::MemoryContext;
1240 /// # use linera_views::map_view::MapView;
1241 /// # use linera_views::views::View;
1242 /// # let context = MemoryContext::new_for_testing(());
1243 /// let mut map: MapView<_, u32, _> = MapView::load(context).await.unwrap();
1244 /// map.insert(&(37 as u32), String::from("Hello"));
1245 /// map.insert(&(49 as u32), String::from("Bonjour"));
1246 /// assert_eq!(
1247 /// map.multi_get_pairs([37 as u32, 49 as u32, 64 as u32])
1248 /// .await
1249 /// .unwrap(),
1250 /// vec![
1251 /// (37 as u32, Some(String::from("Hello"))),
1252 /// (49 as u32, Some(String::from("Bonjour"))),
1253 /// (64 as u32, None)
1254 /// ]
1255 /// );
1256 /// # })
1257 /// ```
1258 pub async fn multi_get_pairs<Q>(
1259 &self,
1260 indices: impl IntoIterator<Item = Q>,
1261 ) -> Result<Vec<(Q, Option<V>)>, ViewError>
1262 where
1263 I: Borrow<Q>,
1264 Q: Serialize + Clone,
1265 {
1266 let indices_vec = indices.into_iter().collect::<Vec<Q>>();
1267 let values = self.multi_get(indices_vec.iter()).await?;
1268 Ok(indices_vec.into_iter().zip(values).collect())
1269 }
1270
1271 /// Obtains a mutable reference to a value at a given position if available
1272 /// ```rust
1273 /// # tokio_test::block_on(async {
1274 /// # use linera_views::context::MemoryContext;
1275 /// # use linera_views::map_view::MapView;
1276 /// # use linera_views::views::View;
1277 /// # let context = MemoryContext::new_for_testing(());
1278 /// let mut map: MapView<_, u32, String> = MapView::load(context).await.unwrap();
1279 /// map.insert(&(37 as u32), String::from("Hello"));
1280 /// assert_eq!(map.get_mut(&(34 as u32)).await.unwrap(), None);
1281 /// let value = map.get_mut(&(37 as u32)).await.unwrap().unwrap();
1282 /// *value = String::from("Hola");
1283 /// assert_eq!(
1284 /// map.get(&(37 as u32)).await.unwrap(),
1285 /// Some(String::from("Hola"))
1286 /// );
1287 /// # })
1288 /// ```
1289 pub async fn get_mut<Q>(&mut self, index: &Q) -> Result<Option<&mut V>, ViewError>
1290 where
1291 I: Borrow<Q>,
1292 Q: Serialize + ?Sized,
1293 {
1294 let short_key = BaseKey::derive_short_key(index)?;
1295 self.map.get_mut(&short_key).await
1296 }
1297}
1298
1299impl<C, I, V> MapView<C, I, V>
1300where
1301 C: Context,
1302 I: Send + DeserializeOwned,
1303 V: Clone + Sync + Serialize + DeserializeOwned + 'static,
1304{
1305 /// Returns the list of indices in the map. The order is determined by serialization.
1306 /// ```rust
1307 /// # tokio_test::block_on(async {
1308 /// # use linera_views::context::MemoryContext;
1309 /// # use linera_views::map_view::MapView;
1310 /// # use linera_views::views::View;
1311 /// # let context = MemoryContext::new_for_testing(());
1312 /// let mut map: MapView<_, u32, String> = MapView::load(context).await.unwrap();
1313 /// map.insert(&(37 as u32), String::from("Hello"));
1314 /// assert_eq!(map.indices().await.unwrap(), vec![37 as u32]);
1315 /// # })
1316 /// ```
1317 pub async fn indices(&self) -> Result<Vec<I>, ViewError> {
1318 let mut indices = Vec::<I>::new();
1319 self.for_each_index(|index: I| {
1320 indices.push(index);
1321 Ok(())
1322 })
1323 .await?;
1324 Ok(indices)
1325 }
1326
1327 /// Applies a function f on each index. Indices are visited in an order
1328 /// determined by the serialization. If the function returns false, then
1329 /// the loop ends prematurely.
1330 /// ```rust
1331 /// # tokio_test::block_on(async {
1332 /// # use linera_views::context::MemoryContext;
1333 /// # use linera_views::map_view::MapView;
1334 /// # use linera_views::views::View;
1335 /// # let context = MemoryContext::new_for_testing(());
1336 /// let mut map: MapView<_, u128, String> = MapView::load(context).await.unwrap();
1337 /// map.insert(&(34 as u128), String::from("Thanks"));
1338 /// map.insert(&(37 as u128), String::from("Spasiba"));
1339 /// map.insert(&(38 as u128), String::from("Merci"));
1340 /// let mut count = 0;
1341 /// map.for_each_index_while(|_index| {
1342 /// count += 1;
1343 /// Ok(count < 2)
1344 /// })
1345 /// .await
1346 /// .unwrap();
1347 /// assert_eq!(count, 2);
1348 /// # })
1349 /// ```
1350 pub async fn for_each_index_while<F>(&self, mut f: F) -> Result<(), ViewError>
1351 where
1352 F: FnMut(I) -> Result<bool, ViewError> + Send,
1353 {
1354 let prefix = Vec::new();
1355 self.map
1356 .for_each_key_while(
1357 |key| {
1358 let index = BaseKey::deserialize_value(key)?;
1359 f(index)
1360 },
1361 prefix,
1362 )
1363 .await?;
1364 Ok(())
1365 }
1366
1367 /// Applies a function f on each index. Indices are visited in the order
1368 /// determined by serialization.
1369 /// ```rust
1370 /// # tokio_test::block_on(async {
1371 /// # use linera_views::context::MemoryContext;
1372 /// # use linera_views::map_view::MapView;
1373 /// # use linera_views::views::View;
1374 /// # let context = MemoryContext::new_for_testing(());
1375 /// let mut map: MapView<_, u128, String> = MapView::load(context).await.unwrap();
1376 /// map.insert(&(34 as u128), String::from("Hello"));
1377 /// let mut count = 0;
1378 /// map.for_each_index(|_index| {
1379 /// count += 1;
1380 /// Ok(())
1381 /// })
1382 /// .await
1383 /// .unwrap();
1384 /// assert_eq!(count, 1);
1385 /// # })
1386 /// ```
1387 pub async fn for_each_index<F>(&self, mut f: F) -> Result<(), ViewError>
1388 where
1389 F: FnMut(I) -> Result<(), ViewError> + Send,
1390 {
1391 let prefix = Vec::new();
1392 self.map
1393 .for_each_key(
1394 |key| {
1395 let index = BaseKey::deserialize_value(key)?;
1396 f(index)
1397 },
1398 prefix,
1399 )
1400 .await?;
1401 Ok(())
1402 }
1403
1404 /// Applies a function f on each index/value pair. Indices and values are
1405 /// visited in an order determined by serialization.
1406 /// If the function returns false, then the loop ends prematurely.
1407 /// ```rust
1408 /// # tokio_test::block_on(async {
1409 /// # use linera_views::context::MemoryContext;
1410 /// # use linera_views::map_view::MapView;
1411 /// # use linera_views::views::View;
1412 /// # let context = MemoryContext::new_for_testing(());
1413 /// let mut map: MapView<_, u128, String> = MapView::load(context).await.unwrap();
1414 /// map.insert(&(34 as u128), String::from("Thanks"));
1415 /// map.insert(&(37 as u128), String::from("Spasiba"));
1416 /// map.insert(&(38 as u128), String::from("Merci"));
1417 /// let mut values = Vec::new();
1418 /// map.for_each_index_value_while(|_index, value| {
1419 /// values.push(value);
1420 /// Ok(values.len() < 2)
1421 /// })
1422 /// .await
1423 /// .unwrap();
1424 /// assert_eq!(values.len(), 2);
1425 /// # })
1426 /// ```
1427 pub async fn for_each_index_value_while<'a, F>(&'a self, mut f: F) -> Result<(), ViewError>
1428 where
1429 F: FnMut(I, Cow<'a, V>) -> Result<bool, ViewError> + Send,
1430 {
1431 let prefix = Vec::new();
1432 self.map
1433 .for_each_key_value_while(
1434 |key, value| {
1435 let index = BaseKey::deserialize_value(key)?;
1436 f(index, value)
1437 },
1438 prefix,
1439 )
1440 .await?;
1441 Ok(())
1442 }
1443
1444 /// Applies a function on each index/value pair. Indices and values are
1445 /// visited in an order determined by serialization.
1446 /// ```rust
1447 /// # tokio_test::block_on(async {
1448 /// # use linera_views::context::MemoryContext;
1449 /// # use linera_views::map_view::MapView;
1450 /// # use linera_views::views::View;
1451 /// # let context = MemoryContext::new_for_testing(());
1452 /// let mut map: MapView<_, Vec<u8>, _> = MapView::load(context).await.unwrap();
1453 /// map.insert(&vec![0, 1], String::from("Hello"));
1454 /// let mut count = 0;
1455 /// map.for_each_index_value(|_index, _value| {
1456 /// count += 1;
1457 /// Ok(())
1458 /// })
1459 /// .await
1460 /// .unwrap();
1461 /// assert_eq!(count, 1);
1462 /// # })
1463 /// ```
1464 pub async fn for_each_index_value<'a, F>(&'a self, mut f: F) -> Result<(), ViewError>
1465 where
1466 F: FnMut(I, Cow<'a, V>) -> Result<(), ViewError> + Send,
1467 {
1468 let prefix = Vec::new();
1469 self.map
1470 .for_each_key_value(
1471 |key, value| {
1472 let index = BaseKey::deserialize_value(key)?;
1473 f(index, value)
1474 },
1475 prefix,
1476 )
1477 .await?;
1478 Ok(())
1479 }
1480}
1481
1482impl<C, I, V> MapView<C, I, V>
1483where
1484 C: Context,
1485 I: Send + DeserializeOwned,
1486 V: Clone + Sync + Send + Serialize + DeserializeOwned + 'static,
1487{
1488 /// Obtains all the `(index,value)` pairs.
1489 /// ```rust
1490 /// # tokio_test::block_on(async {
1491 /// # use linera_views::context::MemoryContext;
1492 /// # use linera_views::map_view::MapView;
1493 /// # use linera_views::views::View;
1494 /// # let context = MemoryContext::new_for_testing(());
1495 /// let mut map: MapView<_, String, _> = MapView::load(context).await.unwrap();
1496 /// map.insert("Italian", String::from("Ciao"));
1497 /// let index_values = map.index_values().await.unwrap();
1498 /// assert_eq!(
1499 /// index_values,
1500 /// vec![("Italian".to_string(), "Ciao".to_string())]
1501 /// );
1502 /// # })
1503 /// ```
1504 pub async fn index_values(&self) -> Result<Vec<(I, V)>, ViewError> {
1505 let mut key_values = Vec::new();
1506 self.for_each_index_value(|index, value| {
1507 let value = value.into_owned();
1508 key_values.push((index, value));
1509 Ok(())
1510 })
1511 .await?;
1512 Ok(key_values)
1513 }
1514
1515 /// Obtains the number of entries in the map
1516 /// ```rust
1517 /// # tokio_test::block_on(async {
1518 /// # use linera_views::context::MemoryContext;
1519 /// # use linera_views::map_view::MapView;
1520 /// # use linera_views::views::View;
1521 /// # let context = MemoryContext::new_for_testing(());
1522 /// let mut map: MapView<_, String, _> = MapView::load(context).await.unwrap();
1523 /// map.insert("Italian", String::from("Ciao"));
1524 /// map.insert("French", String::from("Bonjour"));
1525 /// assert_eq!(map.iterative_count().await.unwrap(), 2);
1526 /// # })
1527 /// ```
1528 pub async fn iterative_count(&self) -> Result<usize, ViewError> {
1529 self.map.iterative_count().await
1530 }
1531}
1532
1533impl<C, I, V> MapView<C, I, V>
1534where
1535 C: Context,
1536 I: Serialize,
1537 V: Default + DeserializeOwned + 'static,
1538{
1539 /// Obtains a mutable reference to a value at a given position.
1540 /// Default value if the index is missing.
1541 /// ```rust
1542 /// # tokio_test::block_on(async {
1543 /// # use linera_views::context::MemoryContext;
1544 /// # use linera_views::map_view::MapView;
1545 /// # use linera_views::views::View;
1546 /// # let context = MemoryContext::new_for_testing(());
1547 /// let mut map: MapView<_, u32, u128> = MapView::load(context).await.unwrap();
1548 /// let value = map.get_mut_or_default(&(34 as u32)).await.unwrap();
1549 /// assert_eq!(*value, 0 as u128);
1550 /// # })
1551 /// ```
1552 pub async fn get_mut_or_default<Q>(&mut self, index: &Q) -> Result<&mut V, ViewError>
1553 where
1554 I: Borrow<Q>,
1555 Q: Sync + Send + Serialize + ?Sized,
1556 {
1557 let short_key = BaseKey::derive_short_key(index)?;
1558 self.map.get_mut_or_default(&short_key).await
1559 }
1560}
1561
1562impl<C, I, V> HashableView for MapView<C, I, V>
1563where
1564 Self: View,
1565 ByteMapView<C, V>: HashableView,
1566{
1567 type Hasher = <ByteMapView<C, V> as HashableView>::Hasher;
1568
1569 async fn hash_mut(&mut self) -> Result<<Self::Hasher as Hasher>::Output, ViewError> {
1570 self.map.hash_mut().await
1571 }
1572
1573 async fn hash(&self) -> Result<<Self::Hasher as Hasher>::Output, ViewError> {
1574 self.map.hash().await
1575 }
1576}
1577
1578/// A map view that uses custom serialization
1579#[derive(Debug, Allocative)]
1580#[allocative(bound = "C, I, V: Allocative")]
1581pub struct CustomMapView<C, I, V> {
1582 /// The underlying map storing entries with custom-serialized keys.
1583 map: ByteMapView<C, V>,
1584 /// Phantom data for the key type.
1585 #[allocative(skip)]
1586 _phantom: PhantomData<I>,
1587}
1588
1589impl<C, I, V> View for CustomMapView<C, I, V>
1590where
1591 C: Context,
1592 I: CustomSerialize + Send + Sync,
1593 V: Serialize + Clone + Send + Sync,
1594{
1595 const NUM_INIT_KEYS: usize = ByteMapView::<C, V>::NUM_INIT_KEYS;
1596
1597 type Context = C;
1598
1599 fn context(&self) -> C {
1600 self.map.context()
1601 }
1602
1603 fn pre_load(context: &C) -> Result<Vec<Vec<u8>>, ViewError> {
1604 ByteMapView::<C, V>::pre_load(context)
1605 }
1606
1607 fn post_load(context: C, values: &[Option<Vec<u8>>]) -> Result<Self, ViewError> {
1608 let map = ByteMapView::post_load(context, values)?;
1609 Ok(CustomMapView {
1610 map,
1611 _phantom: PhantomData,
1612 })
1613 }
1614
1615 fn rollback(&mut self) {
1616 self.map.rollback()
1617 }
1618
1619 async fn has_pending_changes(&self) -> bool {
1620 self.map.has_pending_changes().await
1621 }
1622
1623 fn pre_save(&self, batch: &mut Batch) -> Result<bool, ViewError> {
1624 self.map.pre_save(batch)
1625 }
1626
1627 fn post_save(&mut self) {
1628 self.map.post_save()
1629 }
1630
1631 fn clear(&mut self) {
1632 self.map.clear()
1633 }
1634}
1635
1636impl<C, I, V> ClonableView for CustomMapView<C, I, V>
1637where
1638 Self: View,
1639 ByteMapView<C, V>: ClonableView,
1640{
1641 fn clone_unchecked(&mut self) -> Result<Self, ViewError> {
1642 Ok(CustomMapView {
1643 map: self.map.clone_unchecked()?,
1644 _phantom: PhantomData,
1645 })
1646 }
1647}
1648
1649impl<C: Context, I: CustomSerialize, V> CustomMapView<C, I, V> {
1650 /// Inserts or resets a value.
1651 /// ```rust
1652 /// # tokio_test::block_on(async {
1653 /// # use linera_views::context::MemoryContext;
1654 /// # use linera_views::map_view::CustomMapView;
1655 /// # use linera_views::views::View;
1656 /// # let context = MemoryContext::new_for_testing(());
1657 /// let mut map: CustomMapView<_, u128, _> = CustomMapView::load(context).await.unwrap();
1658 /// map.insert(&(24 as u128), String::from("Hello"));
1659 /// assert_eq!(
1660 /// map.get(&(24 as u128)).await.unwrap(),
1661 /// Some(String::from("Hello"))
1662 /// );
1663 /// # })
1664 /// ```
1665 pub fn insert<Q>(&mut self, index: &Q, value: V) -> Result<(), ViewError>
1666 where
1667 I: Borrow<Q>,
1668 Q: CustomSerialize,
1669 {
1670 let short_key = index.to_custom_bytes()?;
1671 self.map.insert(short_key, value);
1672 Ok(())
1673 }
1674
1675 /// Removes a value. If absent then this does not do anything.
1676 /// ```rust
1677 /// # tokio_test::block_on(async {
1678 /// # use linera_views::context::MemoryContext;
1679 /// # use linera_views::map_view::CustomMapView;
1680 /// # use linera_views::views::View;
1681 /// # let context = MemoryContext::new_for_testing(());
1682 /// let mut map = CustomMapView::<_, u128, _>::load(context).await.unwrap();
1683 /// map.insert(&(37 as u128), String::from("Hello"));
1684 /// map.remove(&(37 as u128));
1685 /// assert_eq!(map.get(&(37 as u128)).await.unwrap(), None);
1686 /// # })
1687 /// ```
1688 pub fn remove<Q>(&mut self, index: &Q) -> Result<(), ViewError>
1689 where
1690 I: Borrow<Q>,
1691 Q: CustomSerialize,
1692 {
1693 let short_key = index.to_custom_bytes()?;
1694 self.map.remove(short_key);
1695 Ok(())
1696 }
1697
1698 /// Obtains the extra data.
1699 pub fn extra(&self) -> &C::Extra {
1700 self.map.extra()
1701 }
1702
1703 /// Returns `true` if the map contains a value for the specified key.
1704 /// ```rust
1705 /// # tokio_test::block_on(async {
1706 /// # use linera_views::context::MemoryContext;
1707 /// # use linera_views::map_view::CustomMapView;
1708 /// # use linera_views::views::View;
1709 /// # let context = MemoryContext::new_for_testing(());
1710 /// let mut map = CustomMapView::<_, u128, _>::load(context).await.unwrap();
1711 /// map.insert(&(24 as u128), String::from("Hello"));
1712 /// assert!(map.contains_key(&(24 as u128)).await.unwrap());
1713 /// assert!(!map.contains_key(&(23 as u128)).await.unwrap());
1714 /// # })
1715 /// ```
1716 pub async fn contains_key<Q>(&self, index: &Q) -> Result<bool, ViewError>
1717 where
1718 I: Borrow<Q>,
1719 Q: CustomSerialize,
1720 {
1721 let short_key = index.to_custom_bytes()?;
1722 self.map.contains_key(&short_key).await
1723 }
1724}
1725
1726impl<C, I, V> CustomMapView<C, I, V>
1727where
1728 C: Context,
1729 I: CustomSerialize,
1730 V: Clone + DeserializeOwned + 'static,
1731{
1732 /// Reads the value at the given position, if any.
1733 /// ```rust
1734 /// # tokio_test::block_on(async {
1735 /// # use linera_views::context::MemoryContext;
1736 /// # use linera_views::map_view::CustomMapView;
1737 /// # use linera_views::views::View;
1738 /// # let context = MemoryContext::new_for_testing(());
1739 /// let mut map = CustomMapView::<_, u128, _>::load(context).await.unwrap();
1740 /// map.insert(&(34 as u128), String::from("Hello"));
1741 /// assert_eq!(
1742 /// map.get(&(34 as u128)).await.unwrap(),
1743 /// Some(String::from("Hello"))
1744 /// );
1745 /// # })
1746 /// ```
1747 pub async fn get<Q>(&self, index: &Q) -> Result<Option<V>, ViewError>
1748 where
1749 I: Borrow<Q>,
1750 Q: CustomSerialize,
1751 {
1752 let short_key = index.to_custom_bytes()?;
1753 self.map.get(&short_key).await
1754 }
1755
1756 /// Read values at several positions, if any.
1757 /// ```rust
1758 /// # tokio_test::block_on(async {
1759 /// # use linera_views::context::MemoryContext;
1760 /// # use linera_views::map_view::CustomMapView;
1761 /// # use linera_views::views::View;
1762 /// # let context = MemoryContext::new_for_testing(());
1763 /// let mut map = CustomMapView::<_, u128, _>::load(context).await.unwrap();
1764 /// map.insert(&(34 as u128), String::from("Hello"));
1765 /// map.insert(&(12 as u128), String::from("Hi"));
1766 /// assert_eq!(
1767 /// map.multi_get(&[34 as u128, 12 as u128, 89 as u128])
1768 /// .await
1769 /// .unwrap(),
1770 /// [Some(String::from("Hello")), Some(String::from("Hi")), None]
1771 /// );
1772 /// # })
1773 /// ```
1774 pub async fn multi_get<'a, Q>(
1775 &self,
1776 indices: impl IntoIterator<Item = &'a Q>,
1777 ) -> Result<Vec<Option<V>>, ViewError>
1778 where
1779 I: Borrow<Q>,
1780 Q: CustomSerialize + 'a,
1781 {
1782 let short_keys = indices
1783 .into_iter()
1784 .map(|index| index.to_custom_bytes())
1785 .collect::<Result<_, _>>()?;
1786 self.map.multi_get(short_keys).await
1787 }
1788
1789 /// Read index-value pairs at several positions, if any.
1790 /// ```rust
1791 /// # tokio_test::block_on(async {
1792 /// # use linera_views::context::MemoryContext;
1793 /// # use linera_views::map_view::CustomMapView;
1794 /// # use linera_views::views::View;
1795 /// # let context = MemoryContext::new_for_testing(());
1796 /// let mut map = CustomMapView::<_, u128, _>::load(context).await.unwrap();
1797 /// map.insert(&(34 as u128), String::from("Hello"));
1798 /// map.insert(&(12 as u128), String::from("Hi"));
1799 /// assert_eq!(
1800 /// map.multi_get_pairs([34 as u128, 12 as u128, 89 as u128])
1801 /// .await
1802 /// .unwrap(),
1803 /// vec![
1804 /// (34 as u128, Some(String::from("Hello"))),
1805 /// (12 as u128, Some(String::from("Hi"))),
1806 /// (89 as u128, None)
1807 /// ]
1808 /// );
1809 /// # })
1810 /// ```
1811 pub async fn multi_get_pairs<Q>(
1812 &self,
1813 indices: impl IntoIterator<Item = Q>,
1814 ) -> Result<Vec<(Q, Option<V>)>, ViewError>
1815 where
1816 I: Borrow<Q>,
1817 Q: CustomSerialize + Clone,
1818 {
1819 let indices_vec = indices.into_iter().collect::<Vec<Q>>();
1820 let values = self.multi_get(indices_vec.iter()).await?;
1821 Ok(indices_vec.into_iter().zip(values).collect())
1822 }
1823
1824 /// Obtains a mutable reference to a value at a given position if available
1825 /// ```rust
1826 /// # tokio_test::block_on(async {
1827 /// # use linera_views::context::MemoryContext;
1828 /// # use linera_views::map_view::CustomMapView;
1829 /// # use linera_views::views::View;
1830 /// # let context = MemoryContext::new_for_testing(());
1831 /// let mut map = CustomMapView::<_, u128, _>::load(context).await.unwrap();
1832 /// map.insert(&(34 as u128), String::from("Hello"));
1833 /// let value = map.get_mut(&(34 as u128)).await.unwrap().unwrap();
1834 /// *value = String::from("Hola");
1835 /// assert_eq!(
1836 /// map.get(&(34 as u128)).await.unwrap(),
1837 /// Some(String::from("Hola"))
1838 /// );
1839 /// # })
1840 /// ```
1841 pub async fn get_mut<Q>(&mut self, index: &Q) -> Result<Option<&mut V>, ViewError>
1842 where
1843 I: Borrow<Q>,
1844 Q: CustomSerialize,
1845 {
1846 let short_key = index.to_custom_bytes()?;
1847 self.map.get_mut(&short_key).await
1848 }
1849}
1850
1851impl<C, I, V> CustomMapView<C, I, V>
1852where
1853 C: Context,
1854 I: Send + CustomSerialize,
1855 V: Clone + Serialize + DeserializeOwned + 'static,
1856{
1857 /// Returns the list of indices in the map. The order is determined
1858 /// by the custom serialization.
1859 /// ```rust
1860 /// # tokio_test::block_on(async {
1861 /// # use linera_views::context::MemoryContext;
1862 /// # use linera_views::map_view::CustomMapView;
1863 /// # use linera_views::views::View;
1864 /// # let context = MemoryContext::new_for_testing(());
1865 /// let mut map = CustomMapView::<_, u128, _>::load(context).await.unwrap();
1866 /// map.insert(&(34 as u128), String::from("Hello"));
1867 /// map.insert(&(37 as u128), String::from("Bonjour"));
1868 /// assert_eq!(map.indices().await.unwrap(), vec![34 as u128, 37 as u128]);
1869 /// # })
1870 /// ```
1871 pub async fn indices(&self) -> Result<Vec<I>, ViewError> {
1872 let mut indices = Vec::<I>::new();
1873 self.for_each_index(|index: I| {
1874 indices.push(index);
1875 Ok(())
1876 })
1877 .await?;
1878 Ok(indices)
1879 }
1880
1881 /// Applies a function f on each index. Indices are visited in an order
1882 /// determined by the custom serialization. If the function returns false,
1883 /// then the loop ends prematurely.
1884 /// ```rust
1885 /// # tokio_test::block_on(async {
1886 /// # use linera_views::context::MemoryContext;
1887 /// # use linera_views::map_view::CustomMapView;
1888 /// # use linera_views::views::View;
1889 /// # let context = MemoryContext::new_for_testing(());
1890 /// let mut map = CustomMapView::load(context).await.unwrap();
1891 /// map.insert(&(34 as u128), String::from("Hello"));
1892 /// map.insert(&(37 as u128), String::from("Hola"));
1893 /// let mut indices = Vec::<u128>::new();
1894 /// map.for_each_index_while(|index| {
1895 /// indices.push(index);
1896 /// Ok(indices.len() < 5)
1897 /// })
1898 /// .await
1899 /// .unwrap();
1900 /// assert_eq!(indices.len(), 2);
1901 /// # })
1902 /// ```
1903 pub async fn for_each_index_while<F>(&self, mut f: F) -> Result<(), ViewError>
1904 where
1905 F: FnMut(I) -> Result<bool, ViewError> + Send,
1906 {
1907 let prefix = Vec::new();
1908 self.map
1909 .for_each_key_while(
1910 |key| {
1911 let index = I::from_custom_bytes(key)?;
1912 f(index)
1913 },
1914 prefix,
1915 )
1916 .await?;
1917 Ok(())
1918 }
1919
1920 /// Applies a function f on each index. Indices are visited in an order
1921 /// determined by the custom serialization.
1922 /// ```rust
1923 /// # tokio_test::block_on(async {
1924 /// # use linera_views::context::MemoryContext;
1925 /// # use linera_views::map_view::CustomMapView;
1926 /// # use linera_views::views::View;
1927 /// # let context = MemoryContext::new_for_testing(());
1928 /// let mut map = CustomMapView::load(context).await.unwrap();
1929 /// map.insert(&(34 as u128), String::from("Hello"));
1930 /// map.insert(&(37 as u128), String::from("Hola"));
1931 /// let mut indices = Vec::<u128>::new();
1932 /// map.for_each_index(|index| {
1933 /// indices.push(index);
1934 /// Ok(())
1935 /// })
1936 /// .await
1937 /// .unwrap();
1938 /// assert_eq!(indices, vec![34, 37]);
1939 /// # })
1940 /// ```
1941 pub async fn for_each_index<F>(&self, mut f: F) -> Result<(), ViewError>
1942 where
1943 F: FnMut(I) -> Result<(), ViewError> + Send,
1944 {
1945 let prefix = Vec::new();
1946 self.map
1947 .for_each_key(
1948 |key| {
1949 let index = I::from_custom_bytes(key)?;
1950 f(index)
1951 },
1952 prefix,
1953 )
1954 .await?;
1955 Ok(())
1956 }
1957
1958 /// Applies a function f on the index/value pairs. Indices and values are
1959 /// visited in an order determined by the custom serialization.
1960 /// If the function returns false, then the loop ends prematurely.
1961 /// ```rust
1962 /// # tokio_test::block_on(async {
1963 /// # use linera_views::context::MemoryContext;
1964 /// # use linera_views::map_view::CustomMapView;
1965 /// # use linera_views::views::View;
1966 /// # let context = MemoryContext::new_for_testing(());
1967 /// let mut map = CustomMapView::<_, u128, String>::load(context)
1968 /// .await
1969 /// .unwrap();
1970 /// map.insert(&(34 as u128), String::from("Hello"));
1971 /// map.insert(&(37 as u128), String::from("Hola"));
1972 /// let mut values = Vec::new();
1973 /// map.for_each_index_value_while(|_index, value| {
1974 /// values.push(value);
1975 /// Ok(values.len() < 5)
1976 /// })
1977 /// .await
1978 /// .unwrap();
1979 /// assert_eq!(values.len(), 2);
1980 /// # })
1981 /// ```
1982 pub async fn for_each_index_value_while<'a, F>(&'a self, mut f: F) -> Result<(), ViewError>
1983 where
1984 F: FnMut(I, Cow<'a, V>) -> Result<bool, ViewError> + Send,
1985 {
1986 let prefix = Vec::new();
1987 self.map
1988 .for_each_key_value_while(
1989 |key, value| {
1990 let index = I::from_custom_bytes(key)?;
1991 f(index, value)
1992 },
1993 prefix,
1994 )
1995 .await?;
1996 Ok(())
1997 }
1998
1999 /// Applies a function f on each index/value pair. Indices and values are
2000 /// visited in an order determined by the custom serialization.
2001 /// ```rust
2002 /// # tokio_test::block_on(async {
2003 /// # use linera_views::context::MemoryContext;
2004 /// # use linera_views::map_view::CustomMapView;
2005 /// # use linera_views::views::View;
2006 /// # let context = MemoryContext::new_for_testing(());
2007 /// let mut map = CustomMapView::<_, u128, _>::load(context).await.unwrap();
2008 /// map.insert(&(34 as u128), String::from("Hello"));
2009 /// map.insert(&(37 as u128), String::from("Hola"));
2010 /// let mut indices = Vec::<u128>::new();
2011 /// map.for_each_index_value(|index, _value| {
2012 /// indices.push(index);
2013 /// Ok(())
2014 /// })
2015 /// .await
2016 /// .unwrap();
2017 /// assert_eq!(indices, vec![34, 37]);
2018 /// # })
2019 /// ```
2020 pub async fn for_each_index_value<'a, F>(&'a self, mut f: F) -> Result<(), ViewError>
2021 where
2022 F: FnMut(I, Cow<'a, V>) -> Result<(), ViewError> + Send,
2023 {
2024 let prefix = Vec::new();
2025 self.map
2026 .for_each_key_value(
2027 |key, value| {
2028 let index = I::from_custom_bytes(key)?;
2029 f(index, value)
2030 },
2031 prefix,
2032 )
2033 .await?;
2034 Ok(())
2035 }
2036}
2037
2038impl<C, I, V> CustomMapView<C, I, V>
2039where
2040 C: Context,
2041 I: Send + CustomSerialize,
2042 V: Clone + Sync + Send + Serialize + DeserializeOwned + 'static,
2043{
2044 /// Obtains all the `(index,value)` pairs.
2045 /// ```rust
2046 /// # tokio_test::block_on(async {
2047 /// # use linera_views::context::MemoryContext;
2048 /// # use linera_views::map_view::CustomMapView;
2049 /// # use linera_views::views::View;
2050 /// # let context = MemoryContext::new_for_testing(());
2051 /// let mut map = CustomMapView::<_, u128, _>::load(context).await.unwrap();
2052 /// map.insert(&(24 as u128), String::from("Ciao"));
2053 /// let index_values = map.index_values().await.unwrap();
2054 /// assert_eq!(index_values, vec![(24 as u128, "Ciao".to_string())]);
2055 /// # })
2056 /// ```
2057 pub async fn index_values(&self) -> Result<Vec<(I, V)>, ViewError> {
2058 let mut key_values = Vec::new();
2059 self.for_each_index_value(|index, value| {
2060 let value = value.into_owned();
2061 key_values.push((index, value));
2062 Ok(())
2063 })
2064 .await?;
2065 Ok(key_values)
2066 }
2067
2068 /// Obtains the number of entries in the map
2069 /// ```rust
2070 /// # tokio_test::block_on(async {
2071 /// # use linera_views::context::MemoryContext;
2072 /// # use linera_views::map_view::CustomMapView;
2073 /// # use linera_views::views::View;
2074 /// # let context = MemoryContext::new_for_testing(());
2075 /// let mut map = CustomMapView::<_, u128, _>::load(context).await.unwrap();
2076 /// map.insert(&(24 as u128), String::from("Ciao"));
2077 /// map.insert(&(37 as u128), String::from("Bonjour"));
2078 /// assert_eq!(map.iterative_count().await.unwrap(), 2);
2079 /// # })
2080 /// ```
2081 pub async fn iterative_count(&self) -> Result<usize, ViewError> {
2082 self.map.iterative_count().await
2083 }
2084}
2085
2086impl<C, I, V> CustomMapView<C, I, V>
2087where
2088 C: Context,
2089 I: CustomSerialize,
2090 V: Default + DeserializeOwned + 'static,
2091{
2092 /// Obtains a mutable reference to a value at a given position.
2093 /// Default value if the index is missing.
2094 /// ```rust
2095 /// # tokio_test::block_on(async {
2096 /// # use linera_views::context::MemoryContext;
2097 /// # use linera_views::map_view::CustomMapView;
2098 /// # use linera_views::views::View;
2099 /// # let context = MemoryContext::new_for_testing(());
2100 /// let mut map = CustomMapView::<_, u128, _>::load(context).await.unwrap();
2101 /// map.insert(&(24 as u128), String::from("Hello"));
2102 /// assert_eq!(
2103 /// *map.get_mut_or_default(&(34 as u128)).await.unwrap(),
2104 /// String::new()
2105 /// );
2106 /// # })
2107 /// ```
2108 pub async fn get_mut_or_default<Q>(&mut self, index: &Q) -> Result<&mut V, ViewError>
2109 where
2110 I: Borrow<Q>,
2111 Q: Send + CustomSerialize,
2112 {
2113 let short_key = index.to_custom_bytes()?;
2114 self.map.get_mut_or_default(&short_key).await
2115 }
2116}
2117
2118impl<C, I, V> HashableView for CustomMapView<C, I, V>
2119where
2120 C: Context,
2121 I: Send + Sync + CustomSerialize,
2122 V: Clone + Send + Sync + Serialize + DeserializeOwned + 'static,
2123{
2124 type Hasher = sha3::Sha3_256;
2125
2126 async fn hash_mut(&mut self) -> Result<<Self::Hasher as Hasher>::Output, ViewError> {
2127 self.map.hash_mut().await
2128 }
2129
2130 async fn hash(&self) -> Result<<Self::Hasher as Hasher>::Output, ViewError> {
2131 self.map.hash().await
2132 }
2133}
2134
2135/// Type wrapping `ByteMapView` while memoizing the hash.
2136pub type HashedByteMapView<C, V> = WrappedHashableContainerView<C, ByteMapView<C, V>, HasherOutput>;
2137
2138/// Wrapper around `ByteMapView` to compute hashes based on the history of changes.
2139pub type HistoricallyHashedByteMapView<C, V> = HistoricallyHashableView<C, ByteMapView<C, V>>;
2140
2141/// Type wrapping `MapView` while memoizing the hash.
2142pub type HashedMapView<C, I, V> = WrappedHashableContainerView<C, MapView<C, I, V>, HasherOutput>;
2143
2144/// Wrapper around `MapView` to compute hashes based on the history of changes.
2145pub type HistoricallyHashedMapView<C, I, V> = HistoricallyHashableView<C, MapView<C, I, V>>;
2146
2147/// Type wrapping `CustomMapView` while memoizing the hash.
2148pub type HashedCustomMapView<C, I, V> =
2149 WrappedHashableContainerView<C, CustomMapView<C, I, V>, HasherOutput>;
2150
2151/// Wrapper around `CustomMapView` to compute hashes based on the history of changes.
2152pub type HistoricallyHashedCustomMapView<C, I, V> =
2153 HistoricallyHashableView<C, CustomMapView<C, I, V>>;
2154
2155#[cfg(with_graphql)]
2156mod graphql {
2157 use std::borrow::Cow;
2158
2159 use super::{ByteMapView, CustomMapView, MapView};
2160 use crate::{
2161 context::Context,
2162 graphql::{hash_name, mangle, Entry, MapInput},
2163 };
2164
2165 impl<C: Send + Sync, V: async_graphql::OutputType> async_graphql::TypeName for ByteMapView<C, V> {
2166 fn type_name() -> Cow<'static, str> {
2167 format!(
2168 "ByteMapView_{}_{:08x}",
2169 mangle(V::type_name()),
2170 hash_name::<V>()
2171 )
2172 .into()
2173 }
2174 }
2175
2176 #[async_graphql::Object(cache_control(no_cache), name_type)]
2177 impl<C, V> ByteMapView<C, V>
2178 where
2179 C: Context,
2180 V: async_graphql::OutputType
2181 + serde::ser::Serialize
2182 + serde::de::DeserializeOwned
2183 + Clone
2184 + Send
2185 + Sync
2186 + 'static,
2187 {
2188 #[graphql(derived(name = "keys"))]
2189 async fn keys_(&self, count: Option<usize>) -> Result<Vec<Vec<u8>>, async_graphql::Error> {
2190 let keys = self.keys().await?;
2191 let it = keys.iter().cloned();
2192 Ok(if let Some(count) = count {
2193 it.take(count).collect()
2194 } else {
2195 it.collect()
2196 })
2197 }
2198
2199 async fn entry(
2200 &self,
2201 key: Vec<u8>,
2202 ) -> Result<Entry<Vec<u8>, Option<V>>, async_graphql::Error> {
2203 Ok(Entry {
2204 value: self.get(&key).await?,
2205 key,
2206 })
2207 }
2208
2209 async fn entries(
2210 &self,
2211 input: Option<MapInput<Vec<u8>>>,
2212 ) -> Result<Vec<Entry<Vec<u8>, Option<V>>>, async_graphql::Error> {
2213 let keys = input
2214 .and_then(|input| input.filters)
2215 .and_then(|filters| filters.keys);
2216 let keys = if let Some(keys) = keys {
2217 keys
2218 } else {
2219 self.keys().await?
2220 };
2221
2222 let values = self.multi_get(keys.clone()).await?;
2223
2224 Ok(keys
2225 .into_iter()
2226 .zip(values)
2227 .map(|(key, value)| Entry { key, value })
2228 .collect())
2229 }
2230 }
2231
2232 impl<C: Send + Sync, I: async_graphql::OutputType, V: async_graphql::OutputType>
2233 async_graphql::TypeName for MapView<C, I, V>
2234 {
2235 fn type_name() -> Cow<'static, str> {
2236 format!(
2237 "MapView_{}_{}_{:08x}",
2238 mangle(I::type_name()),
2239 mangle(V::type_name()),
2240 hash_name::<(I, V)>(),
2241 )
2242 .into()
2243 }
2244 }
2245
2246 #[async_graphql::Object(cache_control(no_cache), name_type)]
2247 impl<C, I, V> MapView<C, I, V>
2248 where
2249 C: Context,
2250 I: async_graphql::OutputType
2251 + async_graphql::InputType
2252 + serde::ser::Serialize
2253 + serde::de::DeserializeOwned
2254 + std::fmt::Debug
2255 + Clone
2256 + Send
2257 + Sync
2258 + 'static,
2259 V: async_graphql::OutputType
2260 + serde::ser::Serialize
2261 + serde::de::DeserializeOwned
2262 + Clone
2263 + Send
2264 + Sync
2265 + 'static,
2266 {
2267 async fn keys(&self, count: Option<usize>) -> Result<Vec<I>, async_graphql::Error> {
2268 let indices = self.indices().await?;
2269 let it = indices.iter().cloned();
2270 Ok(if let Some(count) = count {
2271 it.take(count).collect()
2272 } else {
2273 it.collect()
2274 })
2275 }
2276
2277 #[graphql(derived(name = "count"))]
2278 async fn count_(&self) -> Result<u32, async_graphql::Error> {
2279 let count = self.iterative_count().await?;
2280 u32::try_from(count).map_err(|_| async_graphql::Error::new("count exceeds u32"))
2281 }
2282
2283 async fn entry(&self, key: I) -> Result<Entry<I, Option<V>>, async_graphql::Error> {
2284 Ok(Entry {
2285 value: self.get(&key).await?,
2286 key,
2287 })
2288 }
2289
2290 async fn entries(
2291 &self,
2292 input: Option<MapInput<I>>,
2293 ) -> Result<Vec<Entry<I, Option<V>>>, async_graphql::Error> {
2294 let keys = input
2295 .and_then(|input| input.filters)
2296 .and_then(|filters| filters.keys);
2297 let keys = if let Some(keys) = keys {
2298 keys
2299 } else {
2300 self.indices().await?
2301 };
2302
2303 let values = self.multi_get(&keys).await?;
2304 Ok(values
2305 .into_iter()
2306 .zip(keys)
2307 .map(|(value, key)| Entry { value, key })
2308 .collect())
2309 }
2310 }
2311
2312 impl<C: Send + Sync, I: async_graphql::OutputType, V: async_graphql::OutputType>
2313 async_graphql::TypeName for CustomMapView<C, I, V>
2314 {
2315 fn type_name() -> Cow<'static, str> {
2316 format!(
2317 "CustomMapView_{}_{}_{:08x}",
2318 mangle(I::type_name()),
2319 mangle(V::type_name()),
2320 hash_name::<(I, V)>(),
2321 )
2322 .into()
2323 }
2324 }
2325
2326 #[async_graphql::Object(cache_control(no_cache), name_type)]
2327 impl<C, I, V> CustomMapView<C, I, V>
2328 where
2329 C: Context,
2330 I: async_graphql::OutputType
2331 + async_graphql::InputType
2332 + crate::common::CustomSerialize
2333 + std::fmt::Debug
2334 + Clone
2335 + Send
2336 + Sync
2337 + 'static,
2338 V: async_graphql::OutputType
2339 + serde::ser::Serialize
2340 + serde::de::DeserializeOwned
2341 + Clone
2342 + Send
2343 + Sync
2344 + 'static,
2345 {
2346 async fn keys(&self, count: Option<usize>) -> Result<Vec<I>, async_graphql::Error> {
2347 let indices = self.indices().await?;
2348 let it = indices.iter().cloned();
2349 Ok(if let Some(count) = count {
2350 it.take(count).collect()
2351 } else {
2352 it.collect()
2353 })
2354 }
2355
2356 async fn entry(&self, key: I) -> Result<Entry<I, Option<V>>, async_graphql::Error> {
2357 Ok(Entry {
2358 value: self.get(&key).await?,
2359 key,
2360 })
2361 }
2362
2363 async fn entries(
2364 &self,
2365 input: Option<MapInput<I>>,
2366 ) -> Result<Vec<Entry<I, Option<V>>>, async_graphql::Error> {
2367 let keys = input
2368 .and_then(|input| input.filters)
2369 .and_then(|filters| filters.keys);
2370 let keys = if let Some(keys) = keys {
2371 keys
2372 } else {
2373 self.indices().await?
2374 };
2375
2376 let values = self.multi_get(&keys).await?;
2377 Ok(values
2378 .into_iter()
2379 .zip(keys)
2380 .map(|(value, key)| Entry { value, key })
2381 .collect())
2382 }
2383 }
2384}
2385
2386/// The tests for `Borrow` and `bcs`.
2387#[cfg(test)]
2388pub mod tests {
2389 use std::borrow::Borrow;
2390
2391 fn check_str<T: Borrow<str>>(s: T) {
2392 let ser1 = bcs::to_bytes("Hello").unwrap();
2393 let ser2 = bcs::to_bytes(s.borrow()).unwrap();
2394 assert_eq!(ser1, ser2);
2395 }
2396
2397 fn check_array_u8<T: Borrow<[u8]>>(v: T) {
2398 let ser1 = bcs::to_bytes(&vec![23_u8, 67_u8, 123_u8]).unwrap();
2399 let ser2 = bcs::to_bytes(&v.borrow()).unwrap();
2400 assert_eq!(ser1, ser2);
2401 }
2402
2403 #[test]
2404 fn test_serialization_borrow() {
2405 check_str("Hello".to_string());
2406 check_str("Hello");
2407 //
2408 check_array_u8(vec![23, 67, 123]);
2409 check_array_u8([23, 67, 123]);
2410 }
2411}