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