Skip to content

Commit

Permalink
Implement the index_values and count functions. (#3031)
Browse files Browse the repository at this point in the history
* Add needed functions in the `MapView` and replace relevant code
* Do the same for `CollectionView`, `ReentrantCollectionView` and `SetView`.
* Removal of trait requirements that are not needed.
* Add the correct unit tests.
  • Loading branch information
MathieuDutSik authored Dec 16, 2024
1 parent a3cce00 commit ce92ec9
Show file tree
Hide file tree
Showing 7 changed files with 316 additions and 45 deletions.
9 changes: 1 addition & 8 deletions linera-execution/src/execution_state_actor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,7 @@ where
}

OwnerBalances { callback } => {
let mut balances = Vec::new();
self.system
.balances
.for_each_index_value(|owner, balance| {
balances.push((owner, balance));
Ok(())
})
.await?;
let balances = self.system.balances.index_values().await?;
callback.respond(balances.into_iter().collect());
}

Expand Down
12 changes: 1 addition & 11 deletions linera-execution/src/test_utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,17 +173,7 @@ where
}

async fn registered_application_count(&self) -> anyhow::Result<usize> {
let mut count = 0;

self.registry
.known_applications
.for_each_index(|_| {
count += 1;
Ok(())
})
.await?;

Ok(count)
Ok(self.registry.known_applications.count().await?)
}

async fn register_mock_application_with(
Expand Down
10 changes: 1 addition & 9 deletions linera-execution/tests/contract_runtime_apis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -800,15 +800,7 @@ impl TransferTestEndpoint {
Some(account_owner) => (Amount::ZERO, vec![(account_owner, amount)]),
};

let mut balances = Vec::new();

system
.balances
.for_each_index_value(|owner, balance| {
balances.push((owner, balance));
Ok(())
})
.await?;
let balances = system.balances.index_values().await?;

assert_eq!(*system.balance.get(), expected_chain_balance);
assert_eq!(balances, expected_balances);
Expand Down
67 changes: 65 additions & 2 deletions linera-views/src/views/collection_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,31 @@ where
.await?;
Ok(keys)
}

/// Returns the number of entries in the collection.
/// ```rust
/// # tokio_test::block_on(async {
/// # use linera_views::context::{create_test_memory_context, MemoryContext};
/// # use linera_views::collection_view::ByteCollectionView;
/// # use linera_views::register_view::RegisterView;
/// # use linera_views::views::View;
/// # let context = create_test_memory_context();
/// let mut view: ByteCollectionView<_, RegisterView<_, String>> =
/// ByteCollectionView::load(context).await.unwrap();
/// view.load_entry_mut(&[0, 1]).await.unwrap();
/// view.load_entry_mut(&[0, 2]).await.unwrap();
/// assert_eq!(view.count().await.unwrap(), 2);
/// # })
/// ```
pub async fn count(&self) -> Result<usize, ViewError> {
let mut count = 0;
self.for_each_key(|_key| {
count += 1;
Ok(())
})
.await?;
Ok(count)
}
}

#[async_trait]
Expand Down Expand Up @@ -907,13 +932,32 @@ where
/// ```
pub async fn indices(&self) -> Result<Vec<I>, ViewError> {
let mut indices = Vec::new();
self.for_each_index(|index: I| {
self.for_each_index(|index| {
indices.push(index);
Ok(())
})
.await?;
Ok(indices)
}

/// Returns the number of entries in the collection.
/// ```rust
/// # tokio_test::block_on(async {
/// # use linera_views::context::{create_test_memory_context, MemoryContext};
/// # use linera_views::collection_view::CollectionView;
/// # use linera_views::register_view::RegisterView;
/// # use linera_views::views::View;
/// # let context = create_test_memory_context();
/// let mut view: CollectionView<_, u64, RegisterView<_, String>> =
/// CollectionView::load(context).await.unwrap();
/// view.load_entry_mut(&23).await.unwrap();
/// view.load_entry_mut(&25).await.unwrap();
/// assert_eq!(view.count().await.unwrap(), 2);
/// # })
/// ```
pub async fn count(&self) -> Result<usize, ViewError> {
self.collection.count().await
}
}

impl<C, I, W> CollectionView<C, I, W>
Expand Down Expand Up @@ -1267,13 +1311,32 @@ where
/// ```
pub async fn indices(&self) -> Result<Vec<I>, ViewError> {
let mut indices = Vec::new();
self.for_each_index(|index: I| {
self.for_each_index(|index| {
indices.push(index);
Ok(())
})
.await?;
Ok(indices)
}

/// Returns the number of entries in the collection.
/// ```rust
/// # tokio_test::block_on(async {
/// # use linera_views::context::{create_test_memory_context, MemoryContext};
/// # use linera_views::collection_view::CollectionView;
/// # use linera_views::register_view::RegisterView;
/// # use linera_views::views::View;
/// # let context = create_test_memory_context();
/// let mut view: CollectionView<_, u64, RegisterView<_, String>> =
/// CollectionView::load(context).await.unwrap();
/// view.load_entry_mut(&23).await.unwrap();
/// view.load_entry_mut(&25).await.unwrap();
/// assert_eq!(view.count().await.unwrap(), 2);
/// # })
/// ```
pub async fn count(&self) -> Result<usize, ViewError> {
self.collection.count().await
}
}

impl<C, I, W> CustomCollectionView<C, I, W>
Expand Down
134 changes: 125 additions & 9 deletions linera-views/src/views/map_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ impl<C, V> ByteMapView<C, V>
where
C: Context,
ViewError: From<C::Error>,
V: Sync + Serialize + DeserializeOwned + 'static,
V: Serialize + 'static,
{
/// Applies the function f on each index (aka key) which has the assigned prefix.
/// Keys are visited in the lexicographic order. The shortened key is send to the
Expand Down Expand Up @@ -709,7 +709,7 @@ impl<C, V> ByteMapView<C, V>
where
C: Context,
ViewError: From<C::Error>,
V: Sync + Send + Serialize + DeserializeOwned + 'static,
V: Send + Serialize + DeserializeOwned + 'static,
{
/// Returns the list of keys and values of the map matching a prefix
/// in lexicographic order.
Expand Down Expand Up @@ -824,7 +824,7 @@ impl<C, V> HashableView<C> for ByteMapView<C, V>
where
C: Context + Send + Sync,
ViewError: From<C::Error>,
V: Clone + Send + Sync + Serialize + DeserializeOwned + 'static,
V: Send + Sync + Serialize + 'static,
{
type Hasher = sha3::Sha3_256;

Expand Down Expand Up @@ -866,7 +866,7 @@ impl<C, I, V> View<C> for MapView<C, I, V>
where
C: Context + Send + Sync,
ViewError: From<C::Error>,
I: Send + Sync + Serialize,
I: Sync,
V: Send + Sync + Serialize,
{
const NUM_INIT_KEYS: usize = ByteMapView::<C, V>::NUM_INIT_KEYS;
Expand Down Expand Up @@ -912,7 +912,7 @@ impl<C, I, V> ClonableView<C> for MapView<C, I, V>
where
C: Context + Send + Sync,
ViewError: From<C::Error>,
I: Send + Sync + Serialize,
I: Sync,
V: Clone + Send + Sync + Serialize,
{
fn clone_unchecked(&mut self) -> Result<Self, ViewError> {
Expand Down Expand Up @@ -1068,7 +1068,7 @@ impl<C, I, V> MapView<C, I, V>
where
C: Context + Sync,
ViewError: From<C::Error>,
I: Sync + Send + Serialize + DeserializeOwned,
I: Send + DeserializeOwned,
V: Sync + Serialize + DeserializeOwned + 'static,
{
/// Returns the list of indices in the map. The order is determined by serialization.
Expand Down Expand Up @@ -1250,6 +1250,64 @@ where
}
}

impl<C, I, V> MapView<C, I, V>
where
C: Context + Sync,
ViewError: From<C::Error>,
I: Send + DeserializeOwned,
V: Sync + Send + Serialize + DeserializeOwned + 'static,
{
/// Obtains all the `(index,value)` pairs.
/// ```rust
/// # tokio_test::block_on(async {
/// # use linera_views::context::create_test_memory_context;
/// # use linera_views::map_view::MapView;
/// # use linera_views::views::View;
/// # let context = create_test_memory_context();
/// let mut map: MapView<_, String, _> = MapView::load(context).await.unwrap();
/// map.insert("Italian", String::from("Ciao"));
/// let index_values = map.index_values().await.unwrap();
/// assert_eq!(
/// index_values,
/// vec![("Italian".to_string(), "Ciao".to_string())]
/// );
/// # })
/// ```
pub async fn index_values(&self) -> Result<Vec<(I, V)>, ViewError> {
let prefix = Vec::new();
let mut key_values = Vec::new();
self.map
.for_each_key_value(
|key, bytes| {
let index = C::deserialize_value(key)?;
let value = C::deserialize_value(bytes)?;
key_values.push((index, value));
Ok(())
},
prefix,
)
.await?;
Ok(key_values)
}

/// Obtains the number of entries in the map
/// ```rust
/// # tokio_test::block_on(async {
/// # use linera_views::context::create_test_memory_context;
/// # use linera_views::map_view::MapView;
/// # use linera_views::views::View;
/// # let context = create_test_memory_context();
/// let mut map: MapView<_, String, _> = MapView::load(context).await.unwrap();
/// map.insert("Italian", String::from("Ciao"));
/// map.insert("French", String::from("Bonjour"));
/// assert_eq!(map.count().await.unwrap(), 2);
/// # })
/// ```
pub async fn count(&self) -> Result<usize, ViewError> {
self.map.count().await
}
}

impl<C, I, V> MapView<C, I, V>
where
C: Context + Sync,
Expand Down Expand Up @@ -1512,8 +1570,8 @@ impl<C, I, V> CustomMapView<C, I, V>
where
C: Context + Sync,
ViewError: From<C::Error>,
I: Sync + Send + CustomSerialize,
V: Sync + Serialize + DeserializeOwned + 'static,
I: Send + CustomSerialize,
V: Serialize + DeserializeOwned + 'static,
{
/// Returns the list of indices in the map. The order is determined
/// by the custom serialization.
Expand Down Expand Up @@ -1698,6 +1756,64 @@ where
}
}

impl<C, I, V> CustomMapView<C, I, V>
where
C: Context + Sync,
ViewError: From<C::Error>,
I: Send + CustomSerialize,
V: Sync + Send + Serialize + DeserializeOwned + 'static,
{
/// Obtains all the `(index,value)` pairs.
/// ```rust
/// # tokio_test::block_on(async {
/// # use linera_views::context::create_test_memory_context;
/// # use linera_views::map_view::MapView;
/// # use linera_views::views::View;
/// # let context = create_test_memory_context();
/// let mut map: MapView<_, String, _> = MapView::load(context).await.unwrap();
/// map.insert("Italian", String::from("Ciao"));
/// let index_values = map.index_values().await.unwrap();
/// assert_eq!(
/// index_values,
/// vec![("Italian".to_string(), "Ciao".to_string())]
/// );
/// # })
/// ```
pub async fn index_values(&self) -> Result<Vec<(I, V)>, ViewError> {
let prefix = Vec::new();
let mut key_values = Vec::new();
self.map
.for_each_key_value(
|key, bytes| {
let index = I::from_custom_bytes(key)?;
let value = C::deserialize_value(bytes)?;
key_values.push((index, value));
Ok(())
},
prefix,
)
.await?;
Ok(key_values)
}

/// Obtains the number of entries in the map
/// ```rust
/// # tokio_test::block_on(async {
/// # use linera_views::context::create_test_memory_context;
/// # use linera_views::map_view::MapView;
/// # use linera_views::views::View;
/// # let context = create_test_memory_context();
/// let mut map: MapView<_, String, _> = MapView::load(context).await.unwrap();
/// map.insert("Italian", String::from("Ciao"));
/// map.insert("French", String::from("Bonjour"));
/// assert_eq!(map.count().await.unwrap(), 2);
/// # })
/// ```
pub async fn count(&self) -> Result<usize, ViewError> {
self.map.count().await
}
}

impl<C, I, V> CustomMapView<C, I, V>
where
C: Context + Sync,
Expand All @@ -1723,7 +1839,7 @@ where
pub async fn get_mut_or_default<Q>(&mut self, index: &Q) -> Result<&mut V, ViewError>
where
I: Borrow<Q>,
Q: Sync + Send + Serialize + CustomSerialize,
Q: Send + CustomSerialize,
{
let short_key = index.to_custom_bytes()?;
self.map.get_mut_or_default(&short_key).await
Expand Down
Loading

0 comments on commit ce92ec9

Please sign in to comment.