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 /// Insert or resets a value.
1652 /// ```rust
1653 /// # tokio_test::block_on(async {
1654 /// # use linera_views::context::MemoryContext;
1655 /// # use linera_views::map_view::MapView;
1656 /// # use linera_views::views::View;
1657 /// # let context = MemoryContext::new_for_testing(());
1658 /// let mut map: MapView<_, u128, _> = MapView::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: Serialize + 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::MapView;
1681 /// # use linera_views::views::View;
1682 /// # let context = MemoryContext::new_for_testing(());
1683 /// let mut map = MapView::<_, u128, String>::load(context).await.unwrap();
1684 /// map.remove(&(37 as u128));
1685 /// assert_eq!(map.get(&(37 as u128)).await.unwrap(), None);
1686 /// # })
1687 /// ```
1688 pub fn remove<Q>(&mut self, index: &Q) -> Result<(), ViewError>
1689 where
1690 I: Borrow<Q>,
1691 Q: Serialize + CustomSerialize,
1692 {
1693 let short_key = index.to_custom_bytes()?;
1694 self.map.remove(short_key);
1695 Ok(())
1696 }
1697
1698 /// Obtains the extra data.
1699 pub fn extra(&self) -> &C::Extra {
1700 self.map.extra()
1701 }
1702
1703 /// Returns `true` if the map contains a value for the specified key.
1704 /// ```rust
1705 /// # tokio_test::block_on(async {
1706 /// # use linera_views::context::MemoryContext;
1707 /// # use linera_views::map_view::MapView;
1708 /// # use linera_views::views::View;
1709 /// # let context = MemoryContext::new_for_testing(());
1710 /// let mut map = MapView::<_, u128, String>::load(context).await.unwrap();
1711 /// map.insert(&(37 as u128), String::from("Hello"));
1712 /// assert!(map.contains_key(&(37 as u128)).await.unwrap());
1713 /// assert!(!map.contains_key(&(34 as u128)).await.unwrap());
1714 /// # })
1715 /// ```
1716 pub async fn contains_key<Q>(&self, index: &Q) -> Result<bool, ViewError>
1717 where
1718 I: Borrow<Q>,
1719 Q: Serialize + ?Sized,
1720 {
1721 let short_key = BaseKey::derive_short_key(index)?;
1722 self.map.contains_key(&short_key).await
1723 }
1724}
1725
1726impl<C, I, V> CustomMapView<C, I, V>
1727where
1728 C: Context,
1729 I: CustomSerialize,
1730 V: Clone + DeserializeOwned + 'static,
1731{
1732 /// Reads the value at the given position, if any.
1733 /// ```rust
1734 /// # tokio_test::block_on(async {
1735 /// # use linera_views::context::MemoryContext;
1736 /// # use linera_views::map_view::CustomMapView;
1737 /// # use linera_views::views::View;
1738 /// # let context = MemoryContext::new_for_testing(());
1739 /// let mut map: CustomMapView<MemoryContext<()>, u128, String> =
1740 /// CustomMapView::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<MemoryContext<()>, u128, String> =
1765 /// CustomMapView::load(context).await.unwrap();
1766 /// map.insert(&(34 as u128), String::from("Hello"));
1767 /// map.insert(&(12 as u128), String::from("Hi"));
1768 /// assert_eq!(
1769 /// map.multi_get(&[34 as u128, 12 as u128, 89 as u128])
1770 /// .await
1771 /// .unwrap(),
1772 /// [Some(String::from("Hello")), Some(String::from("Hi")), None]
1773 /// );
1774 /// # })
1775 /// ```
1776 pub async fn multi_get<'a, Q>(
1777 &self,
1778 indices: impl IntoIterator<Item = &'a Q>,
1779 ) -> Result<Vec<Option<V>>, ViewError>
1780 where
1781 I: Borrow<Q>,
1782 Q: CustomSerialize + 'a,
1783 {
1784 let short_keys = indices
1785 .into_iter()
1786 .map(|index| index.to_custom_bytes())
1787 .collect::<Result<_, _>>()?;
1788 self.map.multi_get(short_keys).await
1789 }
1790
1791 /// Read index-value pairs at several positions, if any.
1792 /// ```rust
1793 /// # tokio_test::block_on(async {
1794 /// # use linera_views::context::MemoryContext;
1795 /// # use linera_views::map_view::CustomMapView;
1796 /// # use linera_views::views::View;
1797 /// # let context = MemoryContext::new_for_testing(());
1798 /// let mut map: CustomMapView<MemoryContext<()>, u128, String> =
1799 /// CustomMapView::load(context).await.unwrap();
1800 /// map.insert(&(34 as u128), String::from("Hello"));
1801 /// map.insert(&(12 as u128), String::from("Hi"));
1802 /// assert_eq!(
1803 /// map.multi_get_pairs([34 as u128, 12 as u128, 89 as u128])
1804 /// .await
1805 /// .unwrap(),
1806 /// vec![
1807 /// (34 as u128, Some(String::from("Hello"))),
1808 /// (12 as u128, Some(String::from("Hi"))),
1809 /// (89 as u128, None)
1810 /// ]
1811 /// );
1812 /// # })
1813 /// ```
1814 pub async fn multi_get_pairs<Q>(
1815 &self,
1816 indices: impl IntoIterator<Item = Q>,
1817 ) -> Result<Vec<(Q, Option<V>)>, ViewError>
1818 where
1819 I: Borrow<Q>,
1820 Q: CustomSerialize + Clone,
1821 {
1822 let indices_vec = indices.into_iter().collect::<Vec<Q>>();
1823 let values = self.multi_get(indices_vec.iter()).await?;
1824 Ok(indices_vec.into_iter().zip(values).collect())
1825 }
1826
1827 /// Obtains a mutable reference to a value at a given position if available
1828 /// ```rust
1829 /// # tokio_test::block_on(async {
1830 /// # use linera_views::context::MemoryContext;
1831 /// # use linera_views::map_view::CustomMapView;
1832 /// # use linera_views::views::View;
1833 /// # let context = MemoryContext::new_for_testing(());
1834 /// let mut map: CustomMapView<_, u128, String> = CustomMapView::load(context).await.unwrap();
1835 /// map.insert(&(34 as u128), String::from("Hello"));
1836 /// let value = map.get_mut(&(34 as u128)).await.unwrap().unwrap();
1837 /// *value = String::from("Hola");
1838 /// assert_eq!(
1839 /// map.get(&(34 as u128)).await.unwrap(),
1840 /// Some(String::from("Hola"))
1841 /// );
1842 /// # })
1843 /// ```
1844 pub async fn get_mut<Q>(&mut self, index: &Q) -> Result<Option<&mut V>, ViewError>
1845 where
1846 I: Borrow<Q>,
1847 Q: CustomSerialize,
1848 {
1849 let short_key = index.to_custom_bytes()?;
1850 self.map.get_mut(&short_key).await
1851 }
1852}
1853
1854impl<C, I, V> CustomMapView<C, I, V>
1855where
1856 C: Context,
1857 I: Send + CustomSerialize,
1858 V: Clone + Serialize + DeserializeOwned + 'static,
1859{
1860 /// Returns the list of indices in the map. The order is determined
1861 /// by the custom serialization.
1862 /// ```rust
1863 /// # tokio_test::block_on(async {
1864 /// # use linera_views::context::MemoryContext;
1865 /// # use linera_views::map_view::MapView;
1866 /// # use linera_views::views::View;
1867 /// # let context = MemoryContext::new_for_testing(());
1868 /// let mut map: MapView<_, u128, String> = MapView::load(context).await.unwrap();
1869 /// map.insert(&(34 as u128), String::from("Hello"));
1870 /// map.insert(&(37 as u128), String::from("Bonjour"));
1871 /// assert_eq!(map.indices().await.unwrap(), vec![34 as u128, 37 as u128]);
1872 /// # })
1873 /// ```
1874 pub async fn indices(&self) -> Result<Vec<I>, ViewError> {
1875 let mut indices = Vec::<I>::new();
1876 self.for_each_index(|index: I| {
1877 indices.push(index);
1878 Ok(())
1879 })
1880 .await?;
1881 Ok(indices)
1882 }
1883
1884 /// Applies a function f on each index. Indices are visited in an order
1885 /// determined by the custom serialization. If the function returns false,
1886 /// then the loop ends prematurely.
1887 /// ```rust
1888 /// # tokio_test::block_on(async {
1889 /// # use linera_views::context::MemoryContext;
1890 /// # use linera_views::map_view::CustomMapView;
1891 /// # use linera_views::views::View;
1892 /// # let context = MemoryContext::new_for_testing(());
1893 /// let mut map = CustomMapView::load(context).await.unwrap();
1894 /// map.insert(&(34 as u128), String::from("Hello"));
1895 /// map.insert(&(37 as u128), String::from("Hola"));
1896 /// let mut indices = Vec::<u128>::new();
1897 /// map.for_each_index_while(|index| {
1898 /// indices.push(index);
1899 /// Ok(indices.len() < 5)
1900 /// })
1901 /// .await
1902 /// .unwrap();
1903 /// assert_eq!(indices.len(), 2);
1904 /// # })
1905 /// ```
1906 pub async fn for_each_index_while<F>(&self, mut f: F) -> Result<(), ViewError>
1907 where
1908 F: FnMut(I) -> Result<bool, ViewError> + Send,
1909 {
1910 let prefix = Vec::new();
1911 self.map
1912 .for_each_key_while(
1913 |key| {
1914 let index = I::from_custom_bytes(key)?;
1915 f(index)
1916 },
1917 prefix,
1918 )
1919 .await?;
1920 Ok(())
1921 }
1922
1923 /// Applies a function f on each index. Indices are visited in an order
1924 /// determined by the custom serialization.
1925 /// ```rust
1926 /// # tokio_test::block_on(async {
1927 /// # use linera_views::context::MemoryContext;
1928 /// # use linera_views::map_view::CustomMapView;
1929 /// # use linera_views::views::View;
1930 /// # let context = MemoryContext::new_for_testing(());
1931 /// let mut map = CustomMapView::load(context).await.unwrap();
1932 /// map.insert(&(34 as u128), String::from("Hello"));
1933 /// map.insert(&(37 as u128), String::from("Hola"));
1934 /// let mut indices = Vec::<u128>::new();
1935 /// map.for_each_index(|index| {
1936 /// indices.push(index);
1937 /// Ok(())
1938 /// })
1939 /// .await
1940 /// .unwrap();
1941 /// assert_eq!(indices, vec![34, 37]);
1942 /// # })
1943 /// ```
1944 pub async fn for_each_index<F>(&self, mut f: F) -> Result<(), ViewError>
1945 where
1946 F: FnMut(I) -> Result<(), ViewError> + Send,
1947 {
1948 let prefix = Vec::new();
1949 self.map
1950 .for_each_key(
1951 |key| {
1952 let index = I::from_custom_bytes(key)?;
1953 f(index)
1954 },
1955 prefix,
1956 )
1957 .await?;
1958 Ok(())
1959 }
1960
1961 /// Applies a function f on the index/value pairs. Indices and values are
1962 /// visited in an order determined by the custom serialization.
1963 /// If the function returns false, then the loop ends prematurely.
1964 /// ```rust
1965 /// # tokio_test::block_on(async {
1966 /// # use linera_views::context::MemoryContext;
1967 /// # use linera_views::map_view::CustomMapView;
1968 /// # use linera_views::views::View;
1969 /// # let context = MemoryContext::new_for_testing(());
1970 /// let mut map = CustomMapView::<_, u128, String>::load(context)
1971 /// .await
1972 /// .unwrap();
1973 /// map.insert(&(34 as u128), String::from("Hello"));
1974 /// map.insert(&(37 as u128), String::from("Hola"));
1975 /// let mut values = Vec::new();
1976 /// map.for_each_index_value_while(|_index, value| {
1977 /// values.push(value);
1978 /// Ok(values.len() < 5)
1979 /// })
1980 /// .await
1981 /// .unwrap();
1982 /// assert_eq!(values.len(), 2);
1983 /// # })
1984 /// ```
1985 pub async fn for_each_index_value_while<'a, F>(&'a self, mut f: F) -> Result<(), ViewError>
1986 where
1987 F: FnMut(I, Cow<'a, V>) -> Result<bool, ViewError> + Send,
1988 {
1989 let prefix = Vec::new();
1990 self.map
1991 .for_each_key_value_while(
1992 |key, value| {
1993 let index = I::from_custom_bytes(key)?;
1994 f(index, value)
1995 },
1996 prefix,
1997 )
1998 .await?;
1999 Ok(())
2000 }
2001
2002 /// Applies a function f on each index/value pair. Indices and values are
2003 /// visited in an order determined by the custom serialization.
2004 /// ```rust
2005 /// # tokio_test::block_on(async {
2006 /// # use linera_views::context::MemoryContext;
2007 /// # use linera_views::map_view::CustomMapView;
2008 /// # use linera_views::views::View;
2009 /// # let context = MemoryContext::new_for_testing(());
2010 /// let mut map: CustomMapView<_, u128, String> = CustomMapView::load(context).await.unwrap();
2011 /// map.insert(&(34 as u128), String::from("Hello"));
2012 /// map.insert(&(37 as u128), String::from("Hola"));
2013 /// let mut indices = Vec::<u128>::new();
2014 /// map.for_each_index_value(|index, _value| {
2015 /// indices.push(index);
2016 /// Ok(())
2017 /// })
2018 /// .await
2019 /// .unwrap();
2020 /// assert_eq!(indices, vec![34, 37]);
2021 /// # })
2022 /// ```
2023 pub async fn for_each_index_value<'a, F>(&'a self, mut f: F) -> Result<(), ViewError>
2024 where
2025 F: FnMut(I, Cow<'a, V>) -> Result<(), ViewError> + Send,
2026 {
2027 let prefix = Vec::new();
2028 self.map
2029 .for_each_key_value(
2030 |key, value| {
2031 let index = I::from_custom_bytes(key)?;
2032 f(index, value)
2033 },
2034 prefix,
2035 )
2036 .await?;
2037 Ok(())
2038 }
2039}
2040
2041impl<C, I, V> CustomMapView<C, I, V>
2042where
2043 C: Context,
2044 I: Send + CustomSerialize,
2045 V: Clone + Sync + Send + Serialize + DeserializeOwned + 'static,
2046{
2047 /// Obtains all the `(index,value)` pairs.
2048 /// ```rust
2049 /// # tokio_test::block_on(async {
2050 /// # use linera_views::context::MemoryContext;
2051 /// # use linera_views::map_view::MapView;
2052 /// # use linera_views::views::View;
2053 /// # let context = MemoryContext::new_for_testing(());
2054 /// let mut map: MapView<_, String, _> = MapView::load(context).await.unwrap();
2055 /// map.insert("Italian", String::from("Ciao"));
2056 /// let index_values = map.index_values().await.unwrap();
2057 /// assert_eq!(
2058 /// index_values,
2059 /// vec![("Italian".to_string(), "Ciao".to_string())]
2060 /// );
2061 /// # })
2062 /// ```
2063 pub async fn index_values(&self) -> Result<Vec<(I, V)>, ViewError> {
2064 let mut key_values = Vec::new();
2065 self.for_each_index_value(|index, value| {
2066 let value = value.into_owned();
2067 key_values.push((index, value));
2068 Ok(())
2069 })
2070 .await?;
2071 Ok(key_values)
2072 }
2073
2074 /// Obtains the number of entries in the map
2075 /// ```rust
2076 /// # tokio_test::block_on(async {
2077 /// # use linera_views::context::MemoryContext;
2078 /// # use linera_views::map_view::MapView;
2079 /// # use linera_views::views::View;
2080 /// # let context = MemoryContext::new_for_testing(());
2081 /// let mut map: MapView<_, String, _> = MapView::load(context).await.unwrap();
2082 /// map.insert("Italian", String::from("Ciao"));
2083 /// map.insert("French", String::from("Bonjour"));
2084 /// assert_eq!(map.count().await.unwrap(), 2);
2085 /// # })
2086 /// ```
2087 pub async fn count(&self) -> Result<usize, ViewError> {
2088 self.map.count().await
2089 }
2090}
2091
2092impl<C, I, V> CustomMapView<C, I, V>
2093where
2094 C: Context,
2095 I: CustomSerialize,
2096 V: Default + DeserializeOwned + 'static,
2097{
2098 /// Obtains a mutable reference to a value at a given position.
2099 /// Default value if the index is missing.
2100 /// ```rust
2101 /// # tokio_test::block_on(async {
2102 /// # use linera_views::context::MemoryContext;
2103 /// # use linera_views::map_view::CustomMapView;
2104 /// # use linera_views::views::View;
2105 /// # let context = MemoryContext::new_for_testing(());
2106 /// let mut map: CustomMapView<_, u128, String> = CustomMapView::load(context).await.unwrap();
2107 /// assert_eq!(
2108 /// *map.get_mut_or_default(&(34 as u128)).await.unwrap(),
2109 /// String::new()
2110 /// );
2111 /// # })
2112 /// ```
2113 pub async fn get_mut_or_default<Q>(&mut self, index: &Q) -> Result<&mut V, ViewError>
2114 where
2115 I: Borrow<Q>,
2116 Q: Send + CustomSerialize,
2117 {
2118 let short_key = index.to_custom_bytes()?;
2119 self.map.get_mut_or_default(&short_key).await
2120 }
2121}
2122
2123impl<C, I, V> HashableView for CustomMapView<C, I, V>
2124where
2125 C: Context,
2126 I: Send + Sync + CustomSerialize,
2127 V: Clone + Send + Sync + Serialize + DeserializeOwned + 'static,
2128{
2129 type Hasher = sha3::Sha3_256;
2130
2131 async fn hash_mut(&mut self) -> Result<<Self::Hasher as Hasher>::Output, ViewError> {
2132 self.map.hash_mut().await
2133 }
2134
2135 async fn hash(&self) -> Result<<Self::Hasher as Hasher>::Output, ViewError> {
2136 self.map.hash().await
2137 }
2138}
2139
2140/// Type wrapping `ByteMapView` while memoizing the hash.
2141pub type HashedByteMapView<C, V> = WrappedHashableContainerView<C, ByteMapView<C, V>, HasherOutput>;
2142
2143/// Wrapper around `ByteMapView` to compute hashes based on the history of changes.
2144pub type HistoricallyHashedByteMapView<C, V> = HistoricallyHashableView<C, ByteMapView<C, V>>;
2145
2146/// Type wrapping `MapView` while memoizing the hash.
2147pub type HashedMapView<C, I, V> = WrappedHashableContainerView<C, MapView<C, I, V>, HasherOutput>;
2148
2149/// Wrapper around `MapView` to compute hashes based on the history of changes.
2150pub type HistoricallyHashedMapView<C, I, V> = HistoricallyHashableView<C, MapView<C, I, V>>;
2151
2152/// Type wrapping `CustomMapView` while memoizing the hash.
2153pub type HashedCustomMapView<C, I, V> =
2154 WrappedHashableContainerView<C, CustomMapView<C, I, V>, HasherOutput>;
2155
2156/// Wrapper around `CustomMapView` to compute hashes based on the history of changes.
2157pub type HistoricallyHashedCustomMapView<C, I, V> =
2158 HistoricallyHashableView<C, CustomMapView<C, I, V>>;
2159
2160#[cfg(with_graphql)]
2161mod graphql {
2162 use std::borrow::Cow;
2163
2164 use super::{ByteMapView, CustomMapView, MapView};
2165 use crate::{
2166 context::Context,
2167 graphql::{hash_name, mangle, Entry, MapInput},
2168 };
2169
2170 impl<C: Send + Sync, V: async_graphql::OutputType> async_graphql::TypeName for ByteMapView<C, V> {
2171 fn type_name() -> Cow<'static, str> {
2172 format!(
2173 "ByteMapView_{}_{:08x}",
2174 mangle(V::type_name()),
2175 hash_name::<V>()
2176 )
2177 .into()
2178 }
2179 }
2180
2181 #[async_graphql::Object(cache_control(no_cache), name_type)]
2182 impl<C, V> ByteMapView<C, V>
2183 where
2184 C: Context,
2185 V: async_graphql::OutputType
2186 + serde::ser::Serialize
2187 + serde::de::DeserializeOwned
2188 + Clone
2189 + Send
2190 + Sync
2191 + 'static,
2192 {
2193 #[graphql(derived(name = "keys"))]
2194 async fn keys_(&self, count: Option<usize>) -> Result<Vec<Vec<u8>>, async_graphql::Error> {
2195 let keys = self.keys().await?;
2196 let it = keys.iter().cloned();
2197 Ok(if let Some(count) = count {
2198 it.take(count).collect()
2199 } else {
2200 it.collect()
2201 })
2202 }
2203
2204 async fn entry(
2205 &self,
2206 key: Vec<u8>,
2207 ) -> Result<Entry<Vec<u8>, Option<V>>, async_graphql::Error> {
2208 Ok(Entry {
2209 value: self.get(&key).await?,
2210 key,
2211 })
2212 }
2213
2214 async fn entries(
2215 &self,
2216 input: Option<MapInput<Vec<u8>>>,
2217 ) -> Result<Vec<Entry<Vec<u8>, Option<V>>>, async_graphql::Error> {
2218 let keys = input
2219 .and_then(|input| input.filters)
2220 .and_then(|filters| filters.keys);
2221 let keys = if let Some(keys) = keys {
2222 keys
2223 } else {
2224 self.keys().await?
2225 };
2226
2227 let mut entries = vec![];
2228 for key in keys {
2229 entries.push(Entry {
2230 value: self.get(&key).await?,
2231 key,
2232 })
2233 }
2234
2235 Ok(entries)
2236 }
2237 }
2238
2239 impl<C: Send + Sync, I: async_graphql::OutputType, V: async_graphql::OutputType>
2240 async_graphql::TypeName for MapView<C, I, V>
2241 {
2242 fn type_name() -> Cow<'static, str> {
2243 format!(
2244 "MapView_{}_{}_{:08x}",
2245 mangle(I::type_name()),
2246 mangle(V::type_name()),
2247 hash_name::<(I, V)>(),
2248 )
2249 .into()
2250 }
2251 }
2252
2253 #[async_graphql::Object(cache_control(no_cache), name_type)]
2254 impl<C, I, V> MapView<C, I, V>
2255 where
2256 C: Context,
2257 I: async_graphql::OutputType
2258 + async_graphql::InputType
2259 + serde::ser::Serialize
2260 + serde::de::DeserializeOwned
2261 + std::fmt::Debug
2262 + Clone
2263 + Send
2264 + Sync
2265 + 'static,
2266 V: async_graphql::OutputType
2267 + serde::ser::Serialize
2268 + serde::de::DeserializeOwned
2269 + Clone
2270 + Send
2271 + Sync
2272 + 'static,
2273 {
2274 async fn keys(&self, count: Option<usize>) -> Result<Vec<I>, async_graphql::Error> {
2275 let indices = self.indices().await?;
2276 let it = indices.iter().cloned();
2277 Ok(if let Some(count) = count {
2278 it.take(count).collect()
2279 } else {
2280 it.collect()
2281 })
2282 }
2283
2284 #[graphql(derived(name = "count"))]
2285 async fn count_(&self) -> Result<u32, async_graphql::Error> {
2286 Ok(self.count().await? as u32)
2287 }
2288
2289 async fn entry(&self, key: I) -> Result<Entry<I, Option<V>>, async_graphql::Error> {
2290 Ok(Entry {
2291 value: self.get(&key).await?,
2292 key,
2293 })
2294 }
2295
2296 async fn entries(
2297 &self,
2298 input: Option<MapInput<I>>,
2299 ) -> Result<Vec<Entry<I, Option<V>>>, async_graphql::Error> {
2300 let keys = input
2301 .and_then(|input| input.filters)
2302 .and_then(|filters| filters.keys);
2303 let keys = if let Some(keys) = keys {
2304 keys
2305 } else {
2306 self.indices().await?
2307 };
2308
2309 let values = self.multi_get(&keys).await?;
2310 Ok(values
2311 .into_iter()
2312 .zip(keys)
2313 .map(|(value, key)| Entry { value, key })
2314 .collect())
2315 }
2316 }
2317
2318 impl<C: Send + Sync, I: async_graphql::OutputType, V: async_graphql::OutputType>
2319 async_graphql::TypeName for CustomMapView<C, I, V>
2320 {
2321 fn type_name() -> Cow<'static, str> {
2322 format!(
2323 "CustomMapView_{}_{}_{:08x}",
2324 mangle(I::type_name()),
2325 mangle(V::type_name()),
2326 hash_name::<(I, V)>(),
2327 )
2328 .into()
2329 }
2330 }
2331
2332 #[async_graphql::Object(cache_control(no_cache), name_type)]
2333 impl<C, I, V> CustomMapView<C, I, V>
2334 where
2335 C: Context,
2336 I: async_graphql::OutputType
2337 + async_graphql::InputType
2338 + crate::common::CustomSerialize
2339 + std::fmt::Debug
2340 + Clone
2341 + Send
2342 + Sync
2343 + 'static,
2344 V: async_graphql::OutputType
2345 + serde::ser::Serialize
2346 + serde::de::DeserializeOwned
2347 + Clone
2348 + Send
2349 + Sync
2350 + 'static,
2351 {
2352 async fn keys(&self, count: Option<usize>) -> Result<Vec<I>, async_graphql::Error> {
2353 let indices = self.indices().await?;
2354 let it = indices.iter().cloned();
2355 Ok(if let Some(count) = count {
2356 it.take(count).collect()
2357 } else {
2358 it.collect()
2359 })
2360 }
2361
2362 async fn entry(&self, key: I) -> Result<Entry<I, Option<V>>, async_graphql::Error> {
2363 Ok(Entry {
2364 value: self.get(&key).await?,
2365 key,
2366 })
2367 }
2368
2369 async fn entries(
2370 &self,
2371 input: Option<MapInput<I>>,
2372 ) -> Result<Vec<Entry<I, Option<V>>>, async_graphql::Error> {
2373 let keys = input
2374 .and_then(|input| input.filters)
2375 .and_then(|filters| filters.keys);
2376 let keys = if let Some(keys) = keys {
2377 keys
2378 } else {
2379 self.indices().await?
2380 };
2381
2382 let values = self.multi_get(&keys).await?;
2383 Ok(values
2384 .into_iter()
2385 .zip(keys)
2386 .map(|(value, key)| Entry { value, key })
2387 .collect())
2388 }
2389 }
2390}
2391
2392/// The tests for `Borrow` and `bcs`.
2393#[cfg(test)]
2394pub mod tests {
2395 use std::borrow::Borrow;
2396
2397 fn check_str<T: Borrow<str>>(s: T) {
2398 let ser1 = bcs::to_bytes("Hello").unwrap();
2399 let ser2 = bcs::to_bytes(s.borrow()).unwrap();
2400 assert_eq!(ser1, ser2);
2401 }
2402
2403 fn check_array_u8<T: Borrow<[u8]>>(v: T) {
2404 let ser1 = bcs::to_bytes(&vec![23_u8, 67_u8, 123_u8]).unwrap();
2405 let ser2 = bcs::to_bytes(&v.borrow()).unwrap();
2406 assert_eq!(ser1, ser2);
2407 }
2408
2409 #[test]
2410 fn test_serialization_borrow() {
2411 check_str("Hello".to_string());
2412 check_str("Hello");
2413 //
2414 check_array_u8(vec![23, 67, 123]);
2415 check_array_u8([23, 67, 123]);
2416 }
2417}