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