diff --git a/kuksa_databroker/databroker/src/broker.rs b/kuksa_databroker/databroker/src/broker.rs index 8590af5c9..b19508067 100644 --- a/kuksa_databroker/databroker/src/broker.rs +++ b/kuksa_databroker/databroker/src/broker.rs @@ -850,16 +850,16 @@ pub struct DatabaseWriteAccess<'a, 'b> { permissions: &'b Permissions, } -pub struct MetadataIterator<'a> { - inner: std::collections::hash_map::Iter<'a, i32, Entry>, +pub struct EntryIterator<'a> { + inner: std::collections::hash_map::Values<'a, i32, Entry>, } -impl<'a> Iterator for MetadataIterator<'a> { - type Item = &'a Metadata; +impl<'a> Iterator for EntryIterator<'a> { + type Item = &'a Entry; #[inline] - fn next(&mut self) -> Option<&'a Metadata> { - self.inner.next().map(|(_, entry)| &entry.metadata) + fn next(&mut self) -> Option { + self.inner.next() } #[inline] @@ -910,9 +910,9 @@ impl<'a, 'b> DatabaseReadAccess<'a, 'b> { self.get_metadata_by_id(*id) } - pub fn iter_metadata(&self) -> MetadataIterator { - MetadataIterator { - inner: self.db.entries.iter(), + pub fn iter_entries(&self) -> EntryIterator { + EntryIterator { + inner: self.db.entries.values(), } } } @@ -1118,6 +1118,15 @@ impl<'a, 'b> AuthorizedAccess<'a, 'b> { ) } + pub async fn with_read_lock(&self, f: impl FnOnce(&DatabaseReadAccess) -> T) -> T { + f(&self + .broker + .database + .read() + .await + .authorized_read_access(self.permissions)) + } + pub async fn get_id_by_path(&self, name: &str) -> Option { self.broker .database @@ -1197,27 +1206,38 @@ impl<'a, 'b> AuthorizedAccess<'a, 'b> { .cloned() } - pub async fn for_each_metadata(&self, f: impl FnMut(&Metadata)) { + pub async fn for_each_entry(&self, f: impl FnMut(&Entry)) { self.broker .database .read() .await .authorized_read_access(self.permissions) - .iter_metadata() + .iter_entries() .for_each(f) } - pub async fn map_metadata(&self, f: impl FnMut(&Metadata) -> T) -> Vec { + pub async fn map_entries(&self, f: impl FnMut(&Entry) -> T) -> Vec { self.broker .database .read() .await .authorized_read_access(self.permissions) - .iter_metadata() + .iter_entries() .map(f) .collect() } + pub async fn filter_map_entries(&self, f: impl FnMut(&Entry) -> Option) -> Vec { + self.broker + .database + .read() + .await + .authorized_read_access(self.permissions) + .iter_entries() + .filter_map(f) + .collect() + } + pub async fn update_entries( &self, updates: impl IntoIterator, @@ -2860,7 +2880,7 @@ mod tests { // No permissions let permissions = Permissions::builder().build().unwrap(); let broker = db.authorized_access(&permissions); - let metadata = broker.map_metadata(|metadata| metadata.clone()).await; + let metadata = broker.map_entries(|entry| entry.metadata.clone()).await; for entry in metadata { match entry.path.as_str() { "Vehicle.Test1" => assert_eq!(entry.id, id1), diff --git a/kuksa_databroker/databroker/src/grpc/sdv_databroker_v1/broker.rs b/kuksa_databroker/databroker/src/grpc/sdv_databroker_v1/broker.rs index b30653381..c1ec94cf3 100644 --- a/kuksa_databroker/databroker/src/grpc/sdv_databroker_v1/broker.rs +++ b/kuksa_databroker/databroker/src/grpc/sdv_databroker_v1/broker.rs @@ -208,17 +208,19 @@ impl proto::broker_server::Broker for broker::DataBroker { let list = if request.names.is_empty() { broker - .map_metadata(|metadata| proto::Metadata::from(metadata)) + .map_entries(|entry| proto::Metadata::from(&entry.metadata)) .await } else { - let mut list = Vec::new(); - - for name in request.names { - if let Some(metadata) = broker.get_metadata_by_path(&name).await { - list.push(proto::Metadata::from(&metadata)); - } - } - list + broker + .with_read_lock(|db| { + request + .names + .iter() + .filter_map(|name| db.get_metadata_by_path(name)) + .map(proto::Metadata::from) + .collect::>() + }) + .await }; let reply = proto::GetMetadataReply { list }; Ok(Response::new(reply))