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