@@ -415,6 +415,87 @@ impl<W: View> ByteCollectionView<W::Context, W> {
415415 Ok ( results)
416416 }
417417
418+ /// Load all entries for reading at once.
419+ /// ```rust
420+ /// # tokio_test::block_on(async {
421+ /// # use linera_views::context::MemoryContext;
422+ /// # use linera_views::collection_view::ByteCollectionView;
423+ /// # use linera_views::register_view::RegisterView;
424+ /// # use linera_views::views::View;
425+ /// # let context = MemoryContext::new_for_testing(());
426+ /// let mut view: ByteCollectionView<_, RegisterView<_, String>> =
427+ /// ByteCollectionView::load(context).await.unwrap();
428+ /// {
429+ /// let _subview = view.load_entry_or_insert(&[0, 1]).await.unwrap();
430+ /// }
431+ /// let subviews = view.try_load_all_entries().await.unwrap();
432+ /// assert_eq!(subviews.len(), 1);
433+ /// # })
434+ /// ```
435+ pub async fn try_load_all_entries (
436+ & self ,
437+ ) -> Result < Vec < ( Vec < u8 > , ReadGuardedView < W > ) > , ViewError > {
438+ let updates = self . updates . read ( ) . await ; // Acquire the read lock to prevent writes.
439+ let short_keys = self . keys ( ) . await ?;
440+ let mut results = Vec :: with_capacity ( short_keys. len ( ) ) ;
441+
442+ let mut keys_to_load = Vec :: new ( ) ;
443+ let mut keys_to_load_metadata = Vec :: new ( ) ;
444+ for ( position, short_key) in short_keys. iter ( ) . enumerate ( ) {
445+ match updates. get ( short_key) {
446+ Some ( update) => {
447+ let Update :: Set ( _) = update else {
448+ unreachable ! ( ) ;
449+ } ;
450+ let updates = self . updates . read ( ) . await ;
451+ let view = ReadGuardedView :: Loaded {
452+ updates,
453+ short_key : short_key. clone ( ) ,
454+ } ;
455+ results. push ( ( short_key. clone ( ) , Some ( view) ) ) ;
456+ }
457+ None => {
458+ // If a key is not in `updates`, then it is in storage.
459+ // The key exists since otherwise it would not be in `short_keys`.
460+ // Therefore we have `self.delete_storage_first = false`.
461+ assert ! ( !self . delete_storage_first) ;
462+ results. push ( ( short_key. clone ( ) , None ) ) ;
463+ let key = self
464+ . context
465+ . base_key ( )
466+ . base_tag_index ( KeyTag :: Subview as u8 , short_key) ;
467+ let subview_context = self . context . clone_with_base_key ( key) ;
468+ keys_to_load. extend ( W :: pre_load ( & subview_context) ?) ;
469+ keys_to_load_metadata. push ( ( position, subview_context, short_key. clone ( ) ) ) ;
470+ }
471+ }
472+ }
473+
474+ let values = self
475+ . context
476+ . store ( )
477+ . read_multi_values_bytes ( keys_to_load)
478+ . await ?;
479+
480+ for ( loaded_values, ( position, context, short_key) ) in values
481+ . chunks_exact_or_repeat ( W :: NUM_INIT_KEYS )
482+ . zip ( keys_to_load_metadata)
483+ {
484+ let view = W :: post_load ( context, loaded_values) ?;
485+ let updates = self . updates . read ( ) . await ;
486+ let guarded_view = ReadGuardedView :: NotLoaded {
487+ _updates : updates,
488+ view,
489+ } ;
490+ results[ position] = ( short_key, Some ( guarded_view) ) ;
491+ }
492+
493+ Ok ( results
494+ . into_iter ( )
495+ . map ( |( short_key, view) | ( short_key, view. unwrap ( ) ) )
496+ . collect :: < Vec < _ > > ( ) )
497+ }
498+
418499 /// Resets an entry to the default value.
419500 /// ```rust
420501 /// # tokio_test::block_on(async {
@@ -465,7 +546,7 @@ impl<W: View> ByteCollectionView<W::Context, W> {
465546 /// # })
466547 /// ```
467548 pub async fn contains_key ( & self , short_key : & [ u8 ] ) -> Result < bool , ViewError > {
468- let updates = self . updates . write ( ) . await ;
549+ let updates = self . updates . read ( ) . await ;
469550 Ok ( match updates. get ( short_key) {
470551 Some ( entry) => match entry {
471552 Update :: Set ( _view) => true ,
@@ -584,7 +665,7 @@ impl<W: View> ByteCollectionView<W::Context, W> {
584665 where
585666 F : FnMut ( & [ u8 ] ) -> Result < bool , ViewError > + Send ,
586667 {
587- let updates = self . updates . write ( ) . await ;
668+ let updates = self . updates . read ( ) . await ;
588669 let mut updates = updates. iter ( ) ;
589670 let mut update = updates. next ( ) ;
590671 if !self . delete_storage_first {
@@ -749,10 +830,10 @@ impl<W: HashableView> HashableView for ByteCollectionView<W::Context, W> {
749830 #[ cfg( with_metrics) ]
750831 let _hash_latency = metrics:: COLLECTION_VIEW_HASH_RUNTIME . measure_latency ( ) ;
751832 let mut hasher = sha3:: Sha3_256 :: default ( ) ;
833+ let updates = self . updates . read ( ) . await ; // Acquire the lock to prevent writes.
752834 let keys = self . keys ( ) . await ?;
753835 let count = keys. len ( ) as u32 ;
754836 hasher. update_with_bcs_bytes ( & count) ?;
755- let updates = self . updates . read ( ) . await ;
756837 for key in keys {
757838 hasher. update_with_bytes ( & key) ?;
758839 let hash = match updates. get ( & key) {
@@ -967,6 +1048,37 @@ impl<I: Serialize, W: View> CollectionView<W::Context, I, W> {
9671048 self . collection . try_load_entries ( short_keys) . await
9681049 }
9691050
1051+ /// Load all entries for reading at once.
1052+ /// ```rust
1053+ /// # tokio_test::block_on(async {
1054+ /// # use linera_views::context::MemoryContext;
1055+ /// # use linera_views::collection_view::CollectionView;
1056+ /// # use linera_views::register_view::RegisterView;
1057+ /// # use linera_views::views::View;
1058+ /// # let context = MemoryContext::new_for_testing(());
1059+ /// let mut view: CollectionView<_, u64, RegisterView<_, String>> =
1060+ /// CollectionView::load(context).await.unwrap();
1061+ /// {
1062+ /// let _subview = view.load_entry_or_insert(&23).await.unwrap();
1063+ /// }
1064+ /// let subviews = view.try_load_all_entries().await.unwrap();
1065+ /// assert_eq!(subviews.len(), 1);
1066+ /// # })
1067+ /// ```
1068+ pub async fn try_load_all_entries ( & self ) -> Result < Vec < ( I , ReadGuardedView < W > ) > , ViewError >
1069+ where
1070+ I : DeserializeOwned ,
1071+ {
1072+ let results = self . collection . try_load_all_entries ( ) . await ?;
1073+ results
1074+ . into_iter ( )
1075+ . map ( |( short_key, view) | {
1076+ let index = BaseKey :: deserialize_value ( & short_key) ?;
1077+ Ok ( ( index, view) )
1078+ } )
1079+ . collect ( )
1080+ }
1081+
9701082 /// Resets an entry to the default value.
9711083 /// ```rust
9721084 /// # tokio_test::block_on(async {
@@ -1351,6 +1463,37 @@ impl<I: CustomSerialize, W: View> CustomCollectionView<W::Context, I, W> {
13511463 self . collection . try_load_entries ( short_keys) . await
13521464 }
13531465
1466+ /// Load all entries for reading at once.
1467+ /// ```rust
1468+ /// # tokio_test::block_on(async {
1469+ /// # use linera_views::context::MemoryContext;
1470+ /// # use linera_views::collection_view::CustomCollectionView;
1471+ /// # use linera_views::register_view::RegisterView;
1472+ /// # use linera_views::views::View;
1473+ /// # let context = MemoryContext::new_for_testing(());
1474+ /// let mut view: CustomCollectionView<_, u128, RegisterView<_, String>> =
1475+ /// CustomCollectionView::load(context).await.unwrap();
1476+ /// {
1477+ /// let _subview = view.load_entry_or_insert(&23).await.unwrap();
1478+ /// }
1479+ /// let subviews = view.try_load_all_entries().await.unwrap();
1480+ /// assert_eq!(subviews.len(), 1);
1481+ /// # })
1482+ /// ```
1483+ pub async fn try_load_all_entries ( & self ) -> Result < Vec < ( I , ReadGuardedView < W > ) > , ViewError >
1484+ where
1485+ I : CustomSerialize ,
1486+ {
1487+ let results = self . collection . try_load_all_entries ( ) . await ?;
1488+ results
1489+ . into_iter ( )
1490+ . map ( |( short_key, view) | {
1491+ let index = I :: from_custom_bytes ( & short_key) ?;
1492+ Ok ( ( index, view) )
1493+ } )
1494+ . collect ( )
1495+ }
1496+
13541497 /// Marks the entry so that it is removed in the next flush.
13551498 /// ```rust
13561499 /// # tokio_test::block_on(async {
0 commit comments