1use std::{borrow::Borrow, collections::BTreeMap, marker::PhantomData};
5
6use allocative::Allocative;
7#[cfg(with_metrics)]
8use linera_base::prometheus_util::MeasureLatency as _;
9use serde::{de::DeserializeOwned, Serialize};
10
11use crate::{
12 batch::Batch,
13 common::{CustomSerialize, HasherOutput, Update},
14 context::{BaseKey, Context},
15 hashable_wrapper::WrappedHashableContainerView,
16 historical_hash_wrapper::HistoricallyHashableView,
17 store::ReadableKeyValueStore as _,
18 views::{ClonableView, HashableView, Hasher, ReplaceContext, View, ViewError},
19};
20
21#[cfg(with_metrics)]
22pub(crate) mod metrics {
23 use linera_base::prometheus_util::{exponential_bucket_latencies, register_histogram_vec};
24 use prometheus::HistogramVec;
25
26 linera_base::declare_metrics! {
27 pub static SET_VIEW_HASH_RUNTIME: HistogramVec =
29 register_histogram_vec(
30 "set_view_hash_runtime",
31 "SetView hash runtime",
32 &[],
33 exponential_bucket_latencies(5.0),
34 );
35 }
36}
37
38#[derive(Debug, Allocative)]
40#[allocative(bound = "C")]
41pub struct ByteSetView<C> {
42 #[allocative(skip)]
44 context: C,
45 delete_storage_first: bool,
47 updates: BTreeMap<Vec<u8>, Update<()>>,
49}
50
51impl<C: Context, C2: Context> ReplaceContext<C2> for ByteSetView<C> {
52 type Target = ByteSetView<C2>;
53
54 async fn with_context(
55 &mut self,
56 ctx: impl FnOnce(&Self::Context) -> C2 + Clone,
57 ) -> Self::Target {
58 ByteSetView {
59 context: ctx(&self.context),
60 delete_storage_first: self.delete_storage_first,
61 updates: self.updates.clone(),
62 }
63 }
64}
65
66impl<C: Context> View for ByteSetView<C> {
67 const NUM_INIT_KEYS: usize = 0;
68
69 type Context = C;
70
71 fn context(&self) -> C {
72 self.context.clone()
73 }
74
75 fn pre_load(_context: &C) -> Result<Vec<Vec<u8>>, ViewError> {
76 Ok(Vec::new())
77 }
78
79 fn post_load(context: C, _values: &[Option<Vec<u8>>]) -> Result<Self, ViewError> {
80 Ok(Self {
81 context,
82 delete_storage_first: false,
83 updates: BTreeMap::new(),
84 })
85 }
86
87 fn rollback(&mut self) {
88 self.delete_storage_first = false;
89 self.updates.clear();
90 }
91
92 async fn has_pending_changes(&self) -> bool {
93 if self.delete_storage_first {
94 return true;
95 }
96 !self.updates.is_empty()
97 }
98
99 fn pre_save(&self, batch: &mut Batch) -> Result<bool, ViewError> {
100 let mut delete_view = false;
101 if self.delete_storage_first {
102 delete_view = true;
103 batch.delete_key_prefix(self.context.base_key().bytes.clone());
104 for (index, update) in self.updates.iter() {
105 if let Update::Set(_) = update {
106 let key = self.context.base_key().base_index(index);
107 batch.put_key_value_bytes(key, Vec::new());
108 delete_view = false;
109 }
110 }
111 } else {
112 for (index, update) in self.updates.iter() {
113 let key = self.context.base_key().base_index(index);
114 match update {
115 Update::Removed => batch.delete_key(key),
116 Update::Set(_) => batch.put_key_value_bytes(key, Vec::new()),
117 }
118 }
119 }
120 Ok(delete_view)
121 }
122
123 fn post_save(&mut self) {
124 self.delete_storage_first = false;
125 self.updates.clear();
126 }
127
128 fn clear(&mut self) {
129 self.delete_storage_first = true;
130 self.updates.clear();
131 }
132}
133
134impl<C: Context> ClonableView for ByteSetView<C> {
135 fn clone_unchecked(&mut self) -> Result<Self, ViewError> {
136 Ok(ByteSetView {
137 context: self.context.clone(),
138 delete_storage_first: self.delete_storage_first,
139 updates: self.updates.clone(),
140 })
141 }
142}
143
144impl<C: Context> ByteSetView<C> {
145 pub fn insert(&mut self, short_key: Vec<u8>) {
157 self.updates.insert(short_key, Update::Set(()));
158 }
159
160 pub fn remove(&mut self, short_key: Vec<u8>) {
172 if self.delete_storage_first {
173 self.updates.remove(&short_key);
175 } else {
176 self.updates.insert(short_key, Update::Removed);
177 }
178 }
179
180 pub fn extra(&self) -> &C::Extra {
182 self.context.extra()
183 }
184}
185
186impl<C: Context> ByteSetView<C> {
187 pub async fn contains(&self, short_key: &[u8]) -> Result<bool, ViewError> {
200 if let Some(update) = self.updates.get(short_key) {
201 let value = match update {
202 Update::Removed => false,
203 Update::Set(()) => true,
204 };
205 return Ok(value);
206 }
207 if self.delete_storage_first {
208 return Ok(false);
209 }
210 let key = self.context.base_key().base_index(short_key);
211 Ok(self.context.store().contains_key(&key).await?)
212 }
213}
214
215impl<C: Context> ByteSetView<C> {
216 pub async fn keys(&self) -> Result<Vec<Vec<u8>>, ViewError> {
229 let mut keys = Vec::new();
230 self.for_each_key(|key| {
231 keys.push(key.to_vec());
232 Ok(())
233 })
234 .await?;
235 Ok(keys)
236 }
237
238 pub async fn iterative_count(&self) -> Result<usize, ViewError> {
251 let mut count = 0;
252 self.for_each_key(|_key| {
253 count += 1;
254 Ok(())
255 })
256 .await?;
257 Ok(count)
258 }
259
260 pub async fn for_each_key_while<F>(&self, mut f: F) -> Result<(), ViewError>
283 where
284 F: FnMut(&[u8]) -> Result<bool, ViewError> + Send,
285 {
286 let mut updates = self.updates.iter();
287 let mut update = updates.next();
288 if !self.delete_storage_first {
289 let base = &self.context.base_key().bytes;
290 for index in self.context.store().find_keys_by_prefix(base).await? {
291 loop {
292 match update {
293 Some((key, value)) if key <= &index => {
294 if let Update::Set(_) = value {
295 if !f(key)? {
296 return Ok(());
297 }
298 }
299 update = updates.next();
300 if key == &index {
301 break;
302 }
303 }
304 _ => {
305 if !f(&index)? {
306 return Ok(());
307 }
308 break;
309 }
310 }
311 }
312 }
313 }
314 while let Some((key, value)) = update {
315 if let Update::Set(_) = value {
316 if !f(key)? {
317 return Ok(());
318 }
319 }
320 update = updates.next();
321 }
322 Ok(())
323 }
324
325 pub async fn for_each_key<F>(&self, mut f: F) -> Result<(), ViewError>
347 where
348 F: FnMut(&[u8]) -> Result<(), ViewError> + Send,
349 {
350 self.for_each_key_while(|key| {
351 f(key)?;
352 Ok(true)
353 })
354 .await
355 }
356}
357
358impl<C: Context> HashableView for ByteSetView<C> {
359 type Hasher = sha3::Sha3_256;
360
361 async fn hash_mut(&mut self) -> Result<<Self::Hasher as Hasher>::Output, ViewError> {
362 self.hash().await
363 }
364
365 async fn hash(&self) -> Result<<Self::Hasher as Hasher>::Output, ViewError> {
366 #[cfg(with_metrics)]
367 let _hash_latency = metrics::SET_VIEW_HASH_RUNTIME.measure_latency();
368 let mut hasher = sha3::Sha3_256::default();
369 let mut count = 0u32;
370 self.for_each_key(|key| {
371 count += 1;
372 hasher.update_with_bytes(key)?;
373 Ok(())
374 })
375 .await?;
376 hasher.update_with_bcs_bytes(&count)?;
377 Ok(hasher.finalize())
378 }
379}
380
381#[derive(Debug, Allocative)]
383#[allocative(bound = "C, I")]
384pub struct SetView<C, I> {
385 set: ByteSetView<C>,
387 #[allocative(skip)]
389 _phantom: PhantomData<I>,
390}
391
392impl<C: Context, I: Send + Sync + Serialize, C2: Context> ReplaceContext<C2> for SetView<C, I> {
393 type Target = SetView<C2, I>;
394
395 async fn with_context(
396 &mut self,
397 ctx: impl FnOnce(&Self::Context) -> C2 + Clone,
398 ) -> Self::Target {
399 SetView {
400 set: self.set.with_context(ctx).await,
401 _phantom: self._phantom,
402 }
403 }
404}
405
406impl<C: Context, I: Send + Sync + Serialize> View for SetView<C, I> {
407 const NUM_INIT_KEYS: usize = ByteSetView::<C>::NUM_INIT_KEYS;
408
409 type Context = C;
410
411 fn context(&self) -> C {
412 self.set.context()
413 }
414
415 fn pre_load(context: &C) -> Result<Vec<Vec<u8>>, ViewError> {
416 ByteSetView::<C>::pre_load(context)
417 }
418
419 fn post_load(context: C, values: &[Option<Vec<u8>>]) -> Result<Self, ViewError> {
420 let set = ByteSetView::post_load(context, values)?;
421 Ok(Self {
422 set,
423 _phantom: PhantomData,
424 })
425 }
426
427 fn rollback(&mut self) {
428 self.set.rollback()
429 }
430
431 async fn has_pending_changes(&self) -> bool {
432 self.set.has_pending_changes().await
433 }
434
435 fn pre_save(&self, batch: &mut Batch) -> Result<bool, ViewError> {
436 self.set.pre_save(batch)
437 }
438
439 fn post_save(&mut self) {
440 self.set.post_save()
441 }
442
443 fn clear(&mut self) {
444 self.set.clear()
445 }
446}
447
448impl<C, I> ClonableView for SetView<C, I>
449where
450 C: Context,
451 I: Send + Sync + Serialize,
452{
453 fn clone_unchecked(&mut self) -> Result<Self, ViewError> {
454 Ok(SetView {
455 set: self.set.clone_unchecked()?,
456 _phantom: PhantomData,
457 })
458 }
459}
460
461impl<C: Context, I: Serialize> SetView<C, I> {
462 pub fn insert<Q>(&mut self, index: &Q) -> Result<(), ViewError>
475 where
476 I: Borrow<Q>,
477 Q: Serialize + ?Sized,
478 {
479 let short_key = BaseKey::derive_short_key(index)?;
480 self.set.insert(short_key);
481 Ok(())
482 }
483
484 pub fn remove<Q>(&mut self, index: &Q) -> Result<(), ViewError>
496 where
497 I: Borrow<Q>,
498 Q: Serialize + ?Sized,
499 {
500 let short_key = BaseKey::derive_short_key(index)?;
501 self.set.remove(short_key);
502 Ok(())
503 }
504
505 pub fn extra(&self) -> &C::Extra {
507 self.set.extra()
508 }
509}
510
511impl<C: Context, I: Serialize> SetView<C, I> {
512 pub async fn contains<Q>(&self, index: &Q) -> Result<bool, ViewError>
525 where
526 I: Borrow<Q>,
527 Q: Serialize + ?Sized,
528 {
529 let short_key = BaseKey::derive_short_key(index)?;
530 self.set.contains(&short_key).await
531 }
532}
533
534impl<C: Context, I: Serialize + DeserializeOwned + Send> SetView<C, I> {
535 pub async fn indices(&self) -> Result<Vec<I>, ViewError> {
547 let mut indices = Vec::new();
548 self.for_each_index(|index| {
549 indices.push(index);
550 Ok(())
551 })
552 .await?;
553 Ok(indices)
554 }
555
556 pub async fn iterative_count(&self) -> Result<usize, ViewError> {
568 self.set.iterative_count().await
569 }
570
571 pub async fn for_each_index_while<F>(&self, mut f: F) -> Result<(), ViewError>
595 where
596 F: FnMut(I) -> Result<bool, ViewError> + Send,
597 {
598 self.set
599 .for_each_key_while(|key| {
600 let index = BaseKey::deserialize_value(key)?;
601 f(index)
602 })
603 .await?;
604 Ok(())
605 }
606
607 pub async fn for_each_index<F>(&self, mut f: F) -> Result<(), ViewError>
630 where
631 F: FnMut(I) -> Result<(), ViewError> + Send,
632 {
633 self.set
634 .for_each_key(|key| {
635 let index = BaseKey::deserialize_value(key)?;
636 f(index)
637 })
638 .await?;
639 Ok(())
640 }
641}
642
643impl<C, I> HashableView for SetView<C, I>
644where
645 Self: View,
646 ByteSetView<C>: HashableView,
647{
648 type Hasher = <ByteSetView<C> as HashableView>::Hasher;
649
650 async fn hash_mut(&mut self) -> Result<<Self::Hasher as Hasher>::Output, ViewError> {
651 self.set.hash_mut().await
652 }
653
654 async fn hash(&self) -> Result<<Self::Hasher as Hasher>::Output, ViewError> {
655 self.set.hash().await
656 }
657}
658
659#[derive(Debug, Allocative)]
662#[allocative(bound = "C, I")]
663pub struct CustomSetView<C, I> {
664 set: ByteSetView<C>,
666 #[allocative(skip)]
668 _phantom: PhantomData<I>,
669}
670
671impl<C, I> View for CustomSetView<C, I>
672where
673 C: Context,
674 I: Send + Sync + CustomSerialize,
675{
676 const NUM_INIT_KEYS: usize = ByteSetView::<C>::NUM_INIT_KEYS;
677
678 type Context = C;
679
680 fn context(&self) -> C {
681 self.set.context()
682 }
683
684 fn pre_load(context: &C) -> Result<Vec<Vec<u8>>, ViewError> {
685 ByteSetView::pre_load(context)
686 }
687
688 fn post_load(context: C, values: &[Option<Vec<u8>>]) -> Result<Self, ViewError> {
689 let set = ByteSetView::post_load(context, values)?;
690 Ok(Self {
691 set,
692 _phantom: PhantomData,
693 })
694 }
695
696 fn rollback(&mut self) {
697 self.set.rollback()
698 }
699
700 async fn has_pending_changes(&self) -> bool {
701 self.set.has_pending_changes().await
702 }
703
704 fn pre_save(&self, batch: &mut Batch) -> Result<bool, ViewError> {
705 self.set.pre_save(batch)
706 }
707
708 fn post_save(&mut self) {
709 self.set.post_save()
710 }
711
712 fn clear(&mut self) {
713 self.set.clear()
714 }
715}
716
717impl<C, I> ClonableView for CustomSetView<C, I>
718where
719 C: Context,
720 I: Send + Sync + CustomSerialize,
721{
722 fn clone_unchecked(&mut self) -> Result<Self, ViewError> {
723 Ok(CustomSetView {
724 set: self.set.clone_unchecked()?,
725 _phantom: PhantomData,
726 })
727 }
728}
729
730impl<C: Context, I: CustomSerialize> CustomSetView<C, I> {
731 pub fn insert<Q>(&mut self, index: &Q) -> Result<(), ViewError>
744 where
745 I: Borrow<Q>,
746 Q: CustomSerialize,
747 {
748 let short_key = index.to_custom_bytes()?;
749 self.set.insert(short_key);
750 Ok(())
751 }
752
753 pub fn remove<Q>(&mut self, index: &Q) -> Result<(), ViewError>
766 where
767 I: Borrow<Q>,
768 Q: CustomSerialize,
769 {
770 let short_key = index.to_custom_bytes()?;
771 self.set.remove(short_key);
772 Ok(())
773 }
774
775 pub fn extra(&self) -> &C::Extra {
777 self.set.extra()
778 }
779}
780
781impl<C, I> CustomSetView<C, I>
782where
783 C: Context,
784 I: CustomSerialize,
785{
786 pub async fn contains<Q>(&self, index: &Q) -> Result<bool, ViewError>
800 where
801 I: Borrow<Q>,
802 Q: CustomSerialize,
803 {
804 let short_key = index.to_custom_bytes()?;
805 self.set.contains(&short_key).await
806 }
807}
808
809impl<C, I> CustomSetView<C, I>
810where
811 C: Context,
812 I: Sync + Send + CustomSerialize,
813{
814 pub async fn indices(&self) -> Result<Vec<I>, ViewError> {
829 let mut indices = Vec::new();
830 self.for_each_index(|index| {
831 indices.push(index);
832 Ok(())
833 })
834 .await?;
835 Ok(indices)
836 }
837
838 pub async fn iterative_count(&self) -> Result<usize, ViewError> {
852 self.set.iterative_count().await
853 }
854
855 pub async fn for_each_index_while<F>(&self, mut f: F) -> Result<(), ViewError>
879 where
880 F: FnMut(I) -> Result<bool, ViewError> + Send,
881 {
882 self.set
883 .for_each_key_while(|key| {
884 let index = I::from_custom_bytes(key)?;
885 f(index)
886 })
887 .await?;
888 Ok(())
889 }
890
891 pub async fn for_each_index<F>(&self, mut f: F) -> Result<(), ViewError>
914 where
915 F: FnMut(I) -> Result<(), ViewError> + Send,
916 {
917 self.set
918 .for_each_key(|key| {
919 let index = I::from_custom_bytes(key)?;
920 f(index)
921 })
922 .await?;
923 Ok(())
924 }
925}
926
927impl<C: Context, I> HashableView for CustomSetView<C, I>
928where
929 Self: View,
930{
931 type Hasher = sha3::Sha3_256;
932
933 async fn hash_mut(&mut self) -> Result<<Self::Hasher as Hasher>::Output, ViewError> {
934 self.set.hash_mut().await
935 }
936
937 async fn hash(&self) -> Result<<Self::Hasher as Hasher>::Output, ViewError> {
938 self.set.hash().await
939 }
940}
941
942pub type HashedByteSetView<C> = WrappedHashableContainerView<C, ByteSetView<C>, HasherOutput>;
944
945pub type HistoricallyHashedByteSetView<C> = HistoricallyHashableView<C, ByteSetView<C>>;
947
948pub type HashedSetView<C, I> = WrappedHashableContainerView<C, SetView<C, I>, HasherOutput>;
950
951pub type HistoricallyHashedSetView<C, I> = HistoricallyHashableView<C, SetView<C, I>>;
953
954pub type HashedCustomSetView<C, I> =
956 WrappedHashableContainerView<C, CustomSetView<C, I>, HasherOutput>;
957
958pub type HistoricallyHashedCustomSetView<C, I> = HistoricallyHashableView<C, CustomSetView<C, I>>;
960
961#[cfg(with_graphql)]
962mod graphql {
963 use std::borrow::Cow;
964
965 use serde::{de::DeserializeOwned, Serialize};
966
967 use super::{CustomSetView, SetView};
968 use crate::{
969 common::CustomSerialize,
970 context::Context,
971 graphql::{hash_name, mangle},
972 };
973
974 impl<C: Send + Sync, I: async_graphql::OutputType> async_graphql::TypeName for SetView<C, I> {
975 fn type_name() -> Cow<'static, str> {
976 format!(
977 "SetView_{}_{:08x}",
978 mangle(I::type_name()),
979 hash_name::<I>(),
980 )
981 .into()
982 }
983 }
984
985 #[async_graphql::Object(cache_control(no_cache), name_type)]
986 impl<C, I> SetView<C, I>
987 where
988 C: Context,
989 I: Send + Sync + Serialize + DeserializeOwned + async_graphql::OutputType,
990 {
991 async fn elements(&self, count: Option<usize>) -> Result<Vec<I>, async_graphql::Error> {
992 let mut indices = self.indices().await?;
993 if let Some(count) = count {
994 indices.truncate(count);
995 }
996 Ok(indices)
997 }
998
999 #[graphql(derived(name = "count"))]
1000 async fn count_(&self) -> Result<u32, async_graphql::Error> {
1001 let count = self.iterative_count().await?;
1002 u32::try_from(count).map_err(|_| async_graphql::Error::new("count exceeds u32"))
1003 }
1004 }
1005
1006 impl<C: Send + Sync, I: async_graphql::OutputType> async_graphql::TypeName for CustomSetView<C, I> {
1007 fn type_name() -> Cow<'static, str> {
1008 format!(
1009 "CustomSetView_{}_{:08x}",
1010 mangle(I::type_name()),
1011 hash_name::<I>(),
1012 )
1013 .into()
1014 }
1015 }
1016
1017 #[async_graphql::Object(cache_control(no_cache), name_type)]
1018 impl<C, I> CustomSetView<C, I>
1019 where
1020 C: Context,
1021 I: Send + Sync + CustomSerialize + async_graphql::OutputType,
1022 {
1023 async fn elements(&self, count: Option<usize>) -> Result<Vec<I>, async_graphql::Error> {
1024 let mut indices = self.indices().await?;
1025 if let Some(count) = count {
1026 indices.truncate(count);
1027 }
1028 Ok(indices)
1029 }
1030
1031 #[graphql(derived(name = "count"))]
1032 async fn count_(&self) -> Result<u32, async_graphql::Error> {
1033 let count = self.iterative_count().await?;
1034 u32::try_from(count).map_err(|_| async_graphql::Error::new("count exceeds u32"))
1035 }
1036 }
1037}
1038
1039#[cfg(test)]
1040mod tests {
1041 use super::*;
1042 use crate::{context::MemoryContext, store::WritableKeyValueStore as _};
1043
1044 #[tokio::test]
1045 async fn test_byte_set_view_flush_with_delete_storage_first_and_set_updates(
1046 ) -> Result<(), ViewError> {
1047 let context = MemoryContext::new_for_testing(());
1048 let mut set = ByteSetView::load(context).await?;
1049 assert!(!set.has_pending_changes().await);
1051
1052 set.insert(vec![1, 2, 3]);
1054 set.insert(vec![4, 5, 6]);
1055 assert!(set.has_pending_changes().await);
1057
1058 assert_eq!(set.keys().await?, vec![vec![1, 2, 3], vec![4, 5, 6]]);
1060
1061 let mut batch = Batch::new();
1062 set.pre_save(&mut batch)?;
1063 set.context().store().write_batch(batch).await?;
1064 set.post_save();
1065 assert!(!set.has_pending_changes().await);
1067
1068 assert_eq!(set.keys().await?, vec![vec![1, 2, 3], vec![4, 5, 6]]);
1070 assert_eq!(set.iterative_count().await?, 2);
1071
1072 set.clear();
1074 assert!(set.has_pending_changes().await);
1076
1077 assert!(set.keys().await?.is_empty());
1079
1080 set.insert(vec![7, 8, 9]);
1082 set.insert(vec![10, 11, 12]);
1083 assert!(set.has_pending_changes().await);
1085
1086 assert_eq!(set.keys().await?, vec![vec![7, 8, 9], vec![10, 11, 12]]);
1088
1089 let mut batch = Batch::new();
1091 let delete_view = set.pre_save(&mut batch)?;
1092 assert!(!delete_view);
1095 assert!(!batch.is_empty());
1097
1098 set.context().store().write_batch(batch).await?;
1100 set.post_save();
1101 assert!(!set.has_pending_changes().await);
1103
1104 let new_set = ByteSetView::load(set.context().clone()).await?;
1106 assert!(new_set.contains(&[7, 8, 9]).await?);
1107 assert!(new_set.contains(&[10, 11, 12]).await?);
1108 assert!(!new_set.contains(&[1, 2, 3]).await?);
1109 assert!(!new_set.contains(&[4, 5, 6]).await?);
1110 assert!(!new_set.has_pending_changes().await);
1112
1113 Ok(())
1114 }
1115
1116 #[tokio::test]
1117 async fn test_byte_set_view_flush_with_delete_storage_first_no_set_updates(
1118 ) -> Result<(), ViewError> {
1119 let context = MemoryContext::new_for_testing(());
1120 let mut set = ByteSetView::load(context).await?;
1121
1122 set.insert(vec![1, 2, 3]);
1124 let mut batch = Batch::new();
1125 set.pre_save(&mut batch)?;
1126 set.context().store().write_batch(batch).await?;
1127 set.post_save();
1128
1129 set.clear();
1131 let mut batch = Batch::new();
1132 let delete_view = set.pre_save(&mut batch)?;
1133
1134 assert!(delete_view);
1136
1137 Ok(())
1138 }
1139
1140 #[tokio::test]
1141 async fn test_byte_set_view_flush_with_delete_storage_first_mixed_updates(
1142 ) -> Result<(), ViewError> {
1143 let context = MemoryContext::new_for_testing(());
1144 let mut set = ByteSetView::load(context).await?;
1145
1146 set.insert(vec![1, 2, 3]);
1148 set.insert(vec![4, 5, 6]);
1149 let mut batch = Batch::new();
1150 set.pre_save(&mut batch)?;
1151 set.context().store().write_batch(batch).await?;
1152 set.post_save();
1153
1154 set.clear();
1156
1157 set.insert(vec![7, 8, 9]); set.remove(vec![10, 11, 12]); let mut batch = Batch::new();
1162 let delete_view = set.pre_save(&mut batch)?;
1163
1164 assert!(!delete_view);
1166
1167 Ok(())
1168 }
1169
1170 #[tokio::test]
1171 async fn test_has_pending_changes_comprehensive() -> Result<(), ViewError> {
1172 let context = MemoryContext::new_for_testing(());
1173 let mut set = ByteSetView::load(context).await?;
1174
1175 assert!(!set.has_pending_changes().await);
1177
1178 set.insert(vec![1]);
1180 assert!(set.has_pending_changes().await);
1181
1182 set.insert(vec![2]);
1184 set.insert(vec![3]);
1185 assert!(set.has_pending_changes().await);
1186
1187 let mut batch = Batch::new();
1189 set.pre_save(&mut batch)?;
1190 set.context().store().write_batch(batch).await?;
1191 set.post_save();
1192 assert!(!set.has_pending_changes().await);
1193
1194 set.remove(vec![1]);
1196 assert!(set.has_pending_changes().await);
1197
1198 set.clear();
1200 assert!(set.has_pending_changes().await);
1201
1202 set.insert(vec![4]);
1204 assert!(set.has_pending_changes().await);
1205
1206 set.rollback();
1208 assert!(!set.has_pending_changes().await);
1209
1210 assert!(set.contains(&[2]).await?);
1212 assert!(set.contains(&[3]).await?);
1213
1214 Ok(())
1215 }
1216
1217 #[tokio::test]
1218 async fn test_for_each_key_while_match_update_pattern() -> Result<(), ViewError> {
1219 let context = MemoryContext::new_for_testing(());
1220 let mut set = ByteSetView::load(context).await?;
1221
1222 set.insert(vec![1]);
1224 set.insert(vec![3]);
1225 set.insert(vec![5]);
1226 let mut batch = Batch::new();
1227 set.pre_save(&mut batch)?;
1228 set.context().store().write_batch(batch).await?;
1229 set.post_save();
1230
1231 set.insert(vec![2]); set.insert(vec![4]); let mut keys_processed = Vec::new();
1236
1237 set.for_each_key_while(|key| {
1240 keys_processed.push(key.to_vec());
1241 Ok(true) })
1243 .await?;
1244
1245 assert_eq!(
1247 keys_processed,
1248 vec![vec![1], vec![2], vec![3], vec![4], vec![5]]
1249 );
1250
1251 Ok(())
1252 }
1253
1254 #[tokio::test]
1255 async fn test_for_each_key_while_early_return() -> Result<(), ViewError> {
1256 let context = MemoryContext::new_for_testing(());
1257 let mut set = ByteSetView::load(context).await?;
1258
1259 set.insert(vec![1]);
1261 set.insert(vec![2]);
1262 set.insert(vec![3]);
1263 let mut batch = Batch::new();
1264 set.pre_save(&mut batch)?;
1265 set.context().store().write_batch(batch).await?;
1266 set.post_save();
1267
1268 let mut count = 0;
1269
1270 set.for_each_key_while(|_key| {
1272 count += 1;
1273 if count >= 2 {
1274 Ok(false) } else {
1276 Ok(true)
1277 }
1278 })
1279 .await?;
1280
1281 assert_eq!(count, 2);
1283
1284 Ok(())
1285 }
1286
1287 #[tokio::test]
1288 async fn test_hash_mut_delegation() -> Result<(), ViewError> {
1289 let context = MemoryContext::new_for_testing(());
1290 let mut set = ByteSetView::load(context).await?;
1291
1292 set.insert(vec![1, 2, 3]);
1294 set.insert(vec![4, 5, 6]);
1295
1296 let hash1 = set.hash_mut().await?;
1298 let hash2 = set.hash().await?;
1299
1300 assert_eq!(hash1, hash2);
1302
1303 set.insert(vec![7, 8, 9]);
1305 let hash3 = set.hash_mut().await?;
1306 assert_ne!(hash1, hash3);
1307
1308 Ok(())
1309 }
1310
1311 #[tokio::test]
1312 async fn test_for_each_key_while_early_return_on_update_set() -> Result<(), ViewError> {
1313 let context = MemoryContext::new_for_testing(());
1314 let mut set = ByteSetView::load(context).await?;
1315
1316 set.insert(vec![1]);
1318 set.insert(vec![3]);
1319 let mut batch = Batch::new();
1320 set.pre_save(&mut batch)?;
1321 set.context().store().write_batch(batch).await?;
1322 set.post_save();
1323
1324 set.insert(vec![0]); set.insert(vec![2]); let mut count = 0;
1329
1330 set.for_each_key_while(|key| {
1333 count += 1;
1334 if key == [0] {
1335 Ok(false) } else {
1337 Ok(true)
1338 }
1339 })
1340 .await?;
1341
1342 assert_eq!(count, 1);
1344
1345 Ok(())
1346 }
1347
1348 #[tokio::test]
1349 async fn test_for_each_key_while_early_return_in_remaining_updates() -> Result<(), ViewError> {
1350 let context = MemoryContext::new_for_testing(());
1351 let mut set = ByteSetView::load(context).await?;
1352
1353 set.insert(vec![1]);
1356 set.insert(vec![2]);
1357 set.insert(vec![3]);
1358
1359 let mut count = 0;
1360
1361 set.for_each_key_while(|key| {
1363 count += 1;
1364 if key == [2] {
1365 Ok(false) } else {
1367 Ok(true)
1368 }
1369 })
1370 .await?;
1371
1372 assert_eq!(count, 2);
1374
1375 Ok(())
1376 }
1377
1378 #[tokio::test]
1379 async fn test_contains_update_removed_returns_false() -> Result<(), ViewError> {
1380 let context = MemoryContext::new_for_testing(());
1381 let mut set = ByteSetView::load(context).await?;
1382
1383 assert!(!set.has_pending_changes().await);
1385
1386 set.insert(vec![1, 2, 3]);
1388
1389 assert!(set.has_pending_changes().await);
1391
1392 assert_eq!(set.keys().await?, vec![vec![1, 2, 3]]);
1394
1395 let mut batch = Batch::new();
1396 set.pre_save(&mut batch)?;
1397 set.context().store().write_batch(batch).await?;
1398 set.post_save();
1399
1400 assert!(!set.has_pending_changes().await);
1402
1403 assert_eq!(set.keys().await?, vec![vec![1, 2, 3]]);
1405
1406 assert!(set.contains(&[1, 2, 3]).await?);
1408
1409 set.remove(vec![1, 2, 3]);
1411
1412 assert!(set.has_pending_changes().await);
1414
1415 assert!(set.keys().await?.is_empty());
1417
1418 assert!(!set.contains(&[1, 2, 3]).await?);
1421
1422 Ok(())
1423 }
1424
1425 #[tokio::test]
1426 async fn test_contains_delete_storage_first_returns_false() -> Result<(), ViewError> {
1427 let context = MemoryContext::new_for_testing(());
1428 let mut set = ByteSetView::load(context).await?;
1429
1430 set.insert(vec![1]);
1432 set.insert(vec![2]);
1433 set.insert(vec![3]);
1434 let mut batch = Batch::new();
1435 set.pre_save(&mut batch)?;
1436 set.context().store().write_batch(batch).await?;
1437 set.post_save();
1438
1439 assert!(set.contains(&[1]).await?);
1441 assert!(set.contains(&[2]).await?);
1442 assert!(set.contains(&[3]).await?);
1443
1444 set.clear();
1446
1447 assert!(!set.contains(&[1]).await?);
1450 assert!(!set.contains(&[2]).await?);
1451 assert!(!set.contains(&[3]).await?);
1452
1453 assert!(!set.contains(&[99]).await?);
1455
1456 Ok(())
1457 }
1458
1459 #[tokio::test]
1460 async fn test_contains_delete_storage_first_with_new_additions() -> Result<(), ViewError> {
1461 let context = MemoryContext::new_for_testing(());
1462 let mut set = ByteSetView::load(context).await?;
1463
1464 set.insert(vec![1]);
1466 set.insert(vec![2]);
1467 let mut batch = Batch::new();
1468 set.pre_save(&mut batch)?;
1469 set.context().store().write_batch(batch).await?;
1470 set.post_save();
1471
1472 set.clear();
1474
1475 set.insert(vec![3]);
1477 set.insert(vec![4]);
1478
1479 assert!(!set.contains(&[1]).await?); assert!(!set.contains(&[2]).await?); assert!(set.contains(&[3]).await?); assert!(set.contains(&[4]).await?); Ok(())
1487 }
1488
1489 #[tokio::test]
1490 async fn test_for_each_key_while_update_set_processing_in_stored_loop() -> Result<(), ViewError>
1491 {
1492 let context = MemoryContext::new_for_testing(());
1493 let mut set = ByteSetView::load(context).await?;
1494
1495 set.insert(vec![2]);
1497 set.insert(vec![4]);
1498 set.insert(vec![6]);
1499 let mut batch = Batch::new();
1500 set.pre_save(&mut batch)?;
1501 set.context().store().write_batch(batch).await?;
1502 set.post_save();
1503
1504 set.insert(vec![1]); set.insert(vec![3]); set.remove(vec![5]); let mut processed_keys = Vec::new();
1510
1511 set.for_each_key_while(|key| {
1514 processed_keys.push(key.to_vec());
1515 Ok(true)
1516 })
1517 .await?;
1518
1519 assert_eq!(
1522 processed_keys,
1523 vec![vec![1], vec![2], vec![3], vec![4], vec![6]]
1524 );
1525
1526 Ok(())
1527 }
1528
1529 #[tokio::test]
1530 async fn test_set_view_flush_with_delete_storage_first_and_set_updates() -> Result<(), ViewError>
1531 {
1532 let context = MemoryContext::new_for_testing(());
1533 let mut set = SetView::<_, u32>::load(context).await?;
1534
1535 set.insert(&42)?;
1537 set.insert(&84)?;
1538 let mut batch = Batch::new();
1539 set.pre_save(&mut batch)?;
1540 set.context().store().write_batch(batch).await?;
1541 set.post_save();
1542
1543 set.clear();
1545
1546 set.insert(&123)?;
1548 set.insert(&456)?;
1549
1550 let mut batch = Batch::new();
1551 let delete_view = set.pre_save(&mut batch)?;
1552
1553 assert!(!delete_view);
1555
1556 set.context().store().write_batch(batch).await?;
1558 set.post_save();
1559 let new_set = SetView::<_, u32>::load(set.context().clone()).await?;
1560 assert!(new_set.contains(&123).await?);
1561 assert!(new_set.contains(&456).await?);
1562 assert!(!new_set.contains(&42).await?);
1563 assert!(!new_set.contains(&84).await?);
1564
1565 Ok(())
1566 }
1567
1568 #[tokio::test]
1569 async fn test_set_view_count_delegation() -> Result<(), ViewError> {
1570 let context = MemoryContext::new_for_testing(());
1571 let mut set = SetView::<_, u32>::load(context).await?;
1572
1573 assert!(!set.has_pending_changes().await);
1575
1576 assert_eq!(set.iterative_count().await?, 0);
1578
1579 set.insert(&42)?;
1581
1582 assert!(set.has_pending_changes().await);
1584
1585 assert_eq!(set.indices().await?, vec![42]);
1587
1588 set.insert(&84)?;
1589 set.insert(&126)?;
1590
1591 assert!(set.has_pending_changes().await);
1593
1594 assert_eq!(set.indices().await?, vec![42, 84, 126]);
1596
1597 assert_eq!(set.iterative_count().await?, 3);
1599
1600 Ok(())
1601 }
1602
1603 #[tokio::test]
1604 async fn test_set_view_hash_mut_delegation() -> Result<(), ViewError> {
1605 let context = MemoryContext::new_for_testing(());
1606 let mut set = SetView::<_, u32>::load(context).await?;
1607
1608 set.insert(&42)?;
1610 set.insert(&84)?;
1611 set.insert(&126)?;
1612
1613 let hash1 = set.hash_mut().await?;
1615 let hash2 = set.hash().await?;
1616
1617 assert_eq!(hash1, hash2);
1619
1620 set.insert(&168)?;
1622 let hash3 = set.hash_mut().await?;
1623 assert_ne!(hash1, hash3);
1624
1625 let context2 = MemoryContext::new_for_testing(());
1627 let mut byte_set = ByteSetView::load(context2).await?;
1628
1629 use crate::context::BaseKey;
1631 byte_set.insert(BaseKey::derive_short_key(&42u32)?);
1632 byte_set.insert(BaseKey::derive_short_key(&84u32)?);
1633 byte_set.insert(BaseKey::derive_short_key(&126u32)?);
1634 byte_set.insert(BaseKey::derive_short_key(&168u32)?);
1635
1636 let byte_set_hash = byte_set.hash_mut().await?;
1637 assert_eq!(hash3, byte_set_hash);
1638
1639 Ok(())
1640 }
1641
1642 #[tokio::test]
1644 async fn test_custom_set_view_flush_with_delete_storage_first_and_set_updates(
1645 ) -> Result<(), ViewError> {
1646 let context = MemoryContext::new_for_testing(());
1647 let mut set = CustomSetView::<_, u128>::load(context).await?;
1648
1649 assert!(!set.has_pending_changes().await);
1651
1652 set.insert(&42u128)?;
1654 set.insert(&84u128)?;
1655
1656 assert!(set.has_pending_changes().await);
1658
1659 assert_eq!(set.indices().await?, vec![42u128, 84u128]);
1661
1662 let mut batch = Batch::new();
1663 set.pre_save(&mut batch)?;
1664 set.context().store().write_batch(batch).await?;
1665 set.post_save();
1666
1667 assert!(!set.has_pending_changes().await);
1669
1670 assert_eq!(set.indices().await?, vec![42u128, 84u128]);
1672
1673 set.clear();
1675
1676 assert!(set.has_pending_changes().await);
1678
1679 assert!(set.indices().await?.is_empty());
1681
1682 set.insert(&123u128)?;
1684 set.insert(&456u128)?;
1685
1686 assert!(set.has_pending_changes().await);
1688
1689 assert_eq!(set.indices().await?, vec![123u128, 456u128]);
1691
1692 let mut batch = Batch::new();
1693 let delete_view = set.pre_save(&mut batch)?;
1694
1695 assert!(!delete_view);
1697
1698 set.context().store().write_batch(batch).await?;
1700 set.post_save();
1701
1702 assert!(!set.has_pending_changes().await);
1704
1705 let new_set = CustomSetView::<_, u128>::load(set.context().clone()).await?;
1706 assert!(new_set.contains(&123u128).await?);
1707 assert!(new_set.contains(&456u128).await?);
1708 assert!(!new_set.contains(&42u128).await?);
1709 assert!(!new_set.contains(&84u128).await?);
1710
1711 assert!(!new_set.has_pending_changes().await);
1713
1714 Ok(())
1715 }
1716
1717 #[tokio::test]
1718 async fn test_custom_set_view_contains_update_removed_returns_false() -> Result<(), ViewError> {
1719 let context = MemoryContext::new_for_testing(());
1720 let mut set = CustomSetView::<_, u128>::load(context).await?;
1721
1722 set.insert(&12345u128)?;
1724 let mut batch = Batch::new();
1725 set.pre_save(&mut batch)?;
1726 set.context().store().write_batch(batch).await?;
1727 set.post_save();
1728
1729 assert!(set.contains(&12345u128).await?);
1731
1732 set.remove(&12345u128)?;
1734
1735 assert!(!set.contains(&12345u128).await?);
1737
1738 Ok(())
1739 }
1740
1741 #[tokio::test]
1742 async fn test_custom_set_view_contains_delete_storage_first_returns_false(
1743 ) -> Result<(), ViewError> {
1744 let context = MemoryContext::new_for_testing(());
1745 let mut set = CustomSetView::<_, u128>::load(context).await?;
1746
1747 set.insert(&111u128)?;
1749 set.insert(&222u128)?;
1750 set.insert(&333u128)?;
1751 let mut batch = Batch::new();
1752 set.pre_save(&mut batch)?;
1753 set.context().store().write_batch(batch).await?;
1754 set.post_save();
1755
1756 assert!(set.contains(&111u128).await?);
1758 assert!(set.contains(&222u128).await?);
1759
1760 set.clear();
1762
1763 assert!(!set.contains(&111u128).await?);
1765 assert!(!set.contains(&222u128).await?);
1766 assert!(!set.contains(&333u128).await?);
1767
1768 Ok(())
1769 }
1770
1771 #[tokio::test]
1772 async fn test_custom_set_view_hash_mut_delegation() -> Result<(), ViewError> {
1773 let context = MemoryContext::new_for_testing(());
1774 let mut set = CustomSetView::<_, u128>::load(context).await?;
1775
1776 set.insert(&1000u128)?;
1778 set.insert(&2000u128)?;
1779
1780 let hash1 = set.hash_mut().await?;
1782 let hash2 = set.hash().await?;
1783
1784 assert_eq!(hash1, hash2);
1786
1787 set.insert(&3000u128)?;
1789 let hash3 = set.hash_mut().await?;
1790 assert_ne!(hash1, hash3);
1791
1792 Ok(())
1793 }
1794
1795 #[tokio::test]
1796 async fn test_custom_set_view_for_each_index_while_method_signature() -> Result<(), ViewError> {
1797 let context = MemoryContext::new_for_testing(());
1798 let mut set = CustomSetView::<_, u128>::load(context).await?;
1799 assert_eq!(set.iterative_count().await?, 0);
1800
1801 set.insert(&100u128)?;
1803 set.insert(&200u128)?;
1804 set.insert(&300u128)?;
1805
1806 assert_eq!(set.iterative_count().await?, 3);
1807
1808 let mut collected_indices = Vec::new();
1809
1810 set.for_each_index_while(|index| {
1813 collected_indices.push(index);
1814 Ok(true)
1815 })
1816 .await?;
1817
1818 assert_eq!(collected_indices, vec![100u128, 200u128, 300u128]);
1820
1821 Ok(())
1822 }
1823
1824 #[tokio::test]
1825 async fn test_custom_set_view_rollback() -> Result<(), ViewError> {
1826 let context = MemoryContext::new_for_testing(());
1827 let mut set = CustomSetView::<_, u128>::load(context).await?;
1828
1829 set.insert(&100u128)?;
1831 set.insert(&200u128)?;
1832 let mut batch = Batch::new();
1833 set.pre_save(&mut batch)?;
1834 set.context().store().write_batch(batch).await?;
1835 set.post_save();
1836
1837 assert!(set.contains(&100u128).await?);
1839 assert!(set.contains(&200u128).await?);
1840 assert!(!set.has_pending_changes().await);
1841
1842 set.insert(&300u128)?;
1844 set.remove(&100u128)?;
1845 assert!(set.has_pending_changes().await);
1846
1847 assert!(set.contains(&300u128).await?);
1849 assert!(!set.contains(&100u128).await?);
1850
1851 set.rollback();
1853
1854 assert!(!set.has_pending_changes().await);
1856 assert!(set.contains(&100u128).await?);
1857 assert!(set.contains(&200u128).await?);
1858 assert!(!set.contains(&300u128).await?);
1859
1860 Ok(())
1861 }
1862
1863 #[tokio::test]
1864 async fn test_custom_set_view_clone_unchecked() -> Result<(), ViewError> {
1865 let context = MemoryContext::new_for_testing(());
1866 let mut set = CustomSetView::<_, u128>::load(context).await?;
1867
1868 set.insert(&42u128)?;
1870 set.insert(&84u128)?;
1871
1872 let mut cloned_set = set.clone_unchecked()?;
1874
1875 assert!(cloned_set.contains(&42u128).await?);
1877 assert!(cloned_set.contains(&84u128).await?);
1878
1879 cloned_set.insert(&126u128)?;
1881 assert!(cloned_set.contains(&126u128).await?);
1882 assert!(!set.contains(&126u128).await?);
1883
1884 set.insert(&168u128)?;
1886 assert!(set.contains(&168u128).await?);
1887 assert!(!cloned_set.contains(&168u128).await?);
1888
1889 Ok(())
1890 }
1891
1892 #[cfg(with_graphql)]
1893 mod graphql_tests {
1894 use async_graphql::{EmptyMutation, EmptySubscription, Object, Schema};
1895
1896 use super::*;
1897
1898 struct Query;
1900
1901 #[Object]
1902 impl Query {
1903 async fn test_set(&self) -> TestSetView {
1904 let context = MemoryContext::new_for_testing(());
1905 let mut set = SetView::<_, u32>::load(context).await.unwrap();
1906
1907 set.insert(&42).unwrap();
1909 set.insert(&84).unwrap();
1910 set.insert(&126).unwrap();
1911 set.insert(&168).unwrap();
1912 set.insert(&210).unwrap();
1913
1914 TestSetView { set }
1915 }
1916 }
1917
1918 struct TestSetView {
1919 set: SetView<MemoryContext<()>, u32>,
1920 }
1921
1922 #[Object]
1923 impl TestSetView {
1924 async fn elements(
1925 &self,
1926 count: Option<usize>,
1927 ) -> Result<Vec<u32>, async_graphql::Error> {
1928 let mut indices = self.set.indices().await?;
1930 if let Some(count) = count {
1931 indices.truncate(count);
1933 }
1934 Ok(indices)
1935 }
1936
1937 async fn count(&self) -> Result<u32, async_graphql::Error> {
1938 let count = self.set.iterative_count().await?;
1939 u32::try_from(count).map_err(|_| async_graphql::Error::new("count exceeds u32"))
1940 }
1941 }
1942
1943 #[tokio::test]
1944 async fn test_graphql_elements_without_count() -> Result<(), Box<dyn std::error::Error>> {
1945 let schema = Schema::build(Query, EmptyMutation, EmptySubscription).finish();
1946
1947 let query = r#"
1949 query {
1950 testSet {
1951 elements
1952 }
1953 }
1954 "#;
1955
1956 let result = schema.execute(query).await;
1957 assert!(result.errors.is_empty());
1958
1959 let data = result.data.into_json()?;
1960 let elements = &data["testSet"]["elements"];
1961 assert!(elements.is_array());
1962 assert_eq!(elements.as_array().unwrap().len(), 5);
1963
1964 Ok(())
1965 }
1966
1967 #[tokio::test]
1968 async fn test_graphql_elements_with_count() -> Result<(), Box<dyn std::error::Error>> {
1969 let schema = Schema::build(Query, EmptyMutation, EmptySubscription).finish();
1970
1971 let query = r#"
1973 query {
1974 testSet {
1975 elements(count: 3)
1976 }
1977 }
1978 "#;
1979
1980 let result = schema.execute(query).await;
1981 assert!(result.errors.is_empty());
1982
1983 let data = result.data.into_json()?;
1984 let elements = &data["testSet"]["elements"];
1985 assert!(elements.is_array());
1986 assert_eq!(elements.as_array().unwrap().len(), 3);
1988
1989 Ok(())
1990 }
1991
1992 #[tokio::test]
1993 async fn test_graphql_count_field() -> Result<(), Box<dyn std::error::Error>> {
1994 let schema = Schema::build(Query, EmptyMutation, EmptySubscription).finish();
1995
1996 let query = r#"
1997 query {
1998 testSet {
1999 count
2000 }
2001 }
2002 "#;
2003
2004 let result = schema.execute(query).await;
2005 assert!(result.errors.is_empty());
2006
2007 let data = result.data.into_json()?;
2008 let count = &data["testSet"]["count"];
2009 assert_eq!(count.as_u64().unwrap(), 5);
2010
2011 Ok(())
2012 }
2013 }
2014}