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