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