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