1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use crate::*;
use cyfs_base::*;

use std::sync::Arc;

pub struct ObjectMapNOCCacheAdapter {
    noc: NamedObjectCacheRef,
}

impl ObjectMapNOCCacheAdapter {
    pub fn new(noc: NamedObjectCacheRef) -> Self {
        Self { noc }
    }

    pub fn new_noc_cache(noc: NamedObjectCacheRef) -> ObjectMapNOCCacheRef {
        let ret = Self::new(noc);
        Arc::new(Box::new(ret) as Box<dyn ObjectMapNOCCache>)
    }
}

#[async_trait::async_trait]
impl ObjectMapNOCCache for ObjectMapNOCCacheAdapter {
    async fn exists(&self, dec_id: Option<ObjectId>, object_id: &ObjectId) -> BuckyResult<bool> {
        let noc_req = NamedObjectCacheExistsObjectRequest {
            object_id: object_id.clone(),
            source: RequestSourceInfo::new_local_dec_or_system(dec_id),
        };

        let resp = self.noc.exists_object(&noc_req).await.map_err(|e| {
            error!("exists object map from noc error! id={}, {}", object_id, e);
            e
        })?;

        if resp.meta && resp.object {
            Ok(true)
        } else {
            Ok(false)
        }
    }

    async fn get_object_map_ex(
        &self,
        dec_id: Option<ObjectId>,
        object_id: &ObjectId,
    ) -> BuckyResult<Option<ObjectMapCacheItem>> {
        let noc_req = NamedObjectCacheGetObjectRequest {
            source: RequestSourceInfo::new_local_dec_or_system(dec_id),
            object_id: object_id.clone(),
            last_access_rpath: None,
        };

        let resp = self.noc.get_object(&noc_req).await.map_err(|e| {
            error!("load object map from noc error! id={}, {}", object_id, e);
            e
        })?;

        match resp {
            Some(resp) => {
                match ObjectMap::raw_decode(&resp.object.object_raw) {
                    Ok((object, _)) => {
                        // 首次加载后,直接设置id缓存,减少一次id计算
                        object.direct_set_object_id_on_init(object_id);

                        let item = ObjectMapCacheItem {
                            object,
                            access: AccessString::new(resp.meta.access_string),
                        };
                        Ok(Some(item))
                    }
                    Err(e) => {
                        error!("decode ObjectMap object error: id={}, {}", object_id, e);
                        Err(e)
                    }
                }
            }
            None => Ok(None),
        }
    }

    async fn put_object_map(
        &self,
        dec_id: Option<ObjectId>,
        object_id: ObjectId,
        object: ObjectMap,
        access: Option<AccessString>,
    ) -> BuckyResult<()> {
        let object_raw = object.to_vec().unwrap();
        let object = AnyNamedObject::Standard(StandardObject::ObjectMap(object));
        let object = NONObjectInfo::new(object_id, object_raw, Some(Arc::new(object)));

        let req = NamedObjectCachePutObjectRequest {
            source: RequestSourceInfo::new_local_dec_or_system(dec_id),
            object,
            storage_category: NamedObjectStorageCategory::Storage,
            context: None,
            last_access_rpath: None,
            access_string: access.map(|v| v.value()),
        };

        self.noc.put_object(&req).await.map_err(|e| {
            error!(
                "insert object map to noc error! id={}, dec={:?}, {}",
                object_id, dec_id, e
            );
            e
        })?;

        Ok(())
    }
}