snix_castore/blobstore/
memory.rs1use hashbrown::HashMap;
4use parking_lot::RwLock;
5use std::sync::Arc;
6use tonic::async_trait;
7use tracing::instrument;
8
9use crate::{
10 B3Digest,
11 blobstore::{BlobMeta, BlobStore},
12 composition::{CompositionContext, ServiceBuilder},
13};
14
15#[derive(Default, Clone)]
19pub struct MemoryBlobStore {
20 instance_name: String,
21 db: Arc<RwLock<HashMap<B3Digest, BlobMeta>>>,
22}
23
24#[async_trait]
25impl BlobStore for MemoryBlobStore {
26 #[instrument(skip_all, err, fields(blob.digest=%digest, instance_name=%self.instance_name))]
27 async fn get(&self, digest: &B3Digest) -> Result<Option<BlobMeta>, super::Error> {
28 Ok(self.db.read().get(digest).cloned())
29 }
30
31 #[instrument(skip_all, err, fields(blob.digest=%digest, instance_name=%self.instance_name))]
32 async fn has(&self, digest: &B3Digest) -> Result<bool, super::Error> {
33 Ok(self.db.read().contains_key(digest))
34 }
35 #[instrument(skip_all, err, fields(blob.digest=%digest, instance_name=%self.instance_name))]
36 async fn put(&self, digest: &B3Digest, blob_meta: BlobMeta) -> Result<(), super::Error> {
37 match self.db.write().entry(*digest) {
38 hashbrown::hash_map::Entry::Occupied(_) => {}
39 hashbrown::hash_map::Entry::Vacant(vacant_entry) => {
40 vacant_entry.insert_entry(blob_meta);
41 }
42 }
43
44 Ok(())
45 }
46}
47
48#[derive(serde::Deserialize, Debug)]
50#[serde(deny_unknown_fields)]
51pub struct MemoryBlobStoreConfig {}
52
53impl TryFrom<url::Url> for MemoryBlobStoreConfig {
54 type Error = Box<dyn std::error::Error + Send + Sync>;
55 fn try_from(url: url::Url) -> Result<Self, Self::Error> {
56 if url.has_authority() || !url.path().is_empty() {
58 return Err("invalid url".into());
59 }
60 Ok(MemoryBlobStoreConfig {})
61 }
62}
63
64#[async_trait]
65impl ServiceBuilder for MemoryBlobStoreConfig {
66 type Output = dyn BlobStore;
67 async fn build<'a>(
68 &'a self,
69 instance_name: &str,
70 _context: &CompositionContext,
71 ) -> Result<Arc<Self::Output>, Box<dyn std::error::Error + Send + Sync>> {
72 Ok(Arc::new(MemoryBlobStore {
73 instance_name: instance_name.to_string(),
74 db: Default::default(),
75 }))
76 }
77}