cyfs_base/objects/object_map/
object_map.rs

1use super::cache::*;
2use super::diff::*;
3use super::iterator::*;
4use super::visitor::*;
5use crate::codec as cyfs_base;
6use crate::*;
7use crate::{RawDecode, RawEncode, RawEncodePurpose};
8
9use async_std::sync::Mutex as AsyncMutex;
10use sha2::Digest;
11use std::collections::{btree_map::Entry, BTreeMap, BTreeSet};
12use std::sync::{Arc, Mutex};
13use serde::Serialize;
14
15
16// ObjectMap的key的最大长度
17pub const OBJECT_MAP_KEY_MAX_LEN: usize = 256;
18
19// Map类型的SimpleContent,不需要转换大小的最大安全长度(key=256)
20// pub const OBJECT_MAP_SIMPLE_MAP_CONTENT_SAFE_MAX_LEN: usize = 220;
21
22// Set类型的SimpleContent,不需要转换大小的最大安全长度
23// pub const OBJECT_MAP_SIMPLE_SET_CONTENT_SAFE_MAX_LEN: usize = 2040;
24
25// desc部分除去content后的预留长度,当前版本是19个bytes,预留一些空间
26pub const OBJECT_MAP_DESC_FIELDS_RESERVED_SIZE: u8 = 64;
27
28// 对象content编码后的最大长度
29pub const OBJECT_MAP_CONTENT_MAX_ENCODE_SIZE: u64 =
30    (u16::MAX - OBJECT_MAP_DESC_FIELDS_RESERVED_SIZE as u16) as u64;
31
32// SUB模式下的一致性hash的固定长度
33const SUB_LIST_CONST_LENGTH: u64 = 1900;
34
35// 这是一组用来快速测试多级objectmap的配置参数
36/*
37// Map类型的SimpleContent,不需要转换大小的最大安全长度(key=256)
38pub const OBJECT_MAP_SIMPLE_MAP_CONTENT_SAFE_MAX_LEN: usize = 3;
39
40// Set类型的SimpleContent,不需要转换大小的最大安全长度
41pub const OBJECT_MAP_SIMPLE_SET_CONTENT_SAFE_MAX_LEN: usize = 3;
42
43// 对象编码后的最大长度
44pub const OBJECT_MAP_CONTENT_MAX_ENCODE_SIZE: u64 = 200;
45
46// SUB模式下的一致性hash的固定长度
47const SUB_LIST_CONST_LENGTH: u64 = 2;
48*/
49
50
51#[derive(Debug, Clone, Copy, Eq, PartialEq)]
52pub enum ObjectMapCreateStrategy {
53    NotCreate = 0,
54    CreateNew = 1,
55    CreateIfNotExists = 2,
56}
57
58pub type ObjectMapRef = Arc<AsyncMutex<ObjectMap>>;
59
60#[derive(Clone, Debug, RawEncode, RawDecode)]
61pub struct MapContentT<T>
62where
63    T: Send
64        + Sync
65        + Clone
66        + Eq
67        + PartialEq
68        + std::fmt::Display
69        + RawEncode
70        + IntoObjectMapContentItem,
71{
72    values: BTreeMap<String, T>,
73
74    #[cyfs(skip)]
75    dirty: bool,
76}
77
78impl<T> MapContentT<T>
79where
80    T: Send
81        + Sync
82        + Clone
83        + Eq
84        + PartialEq
85        + std::fmt::Display
86        + RawEncode
87        + IntoObjectMapContentItem,
88{
89    pub fn new() -> Self {
90        Self {
91            values: BTreeMap::new(),
92            dirty: false,
93        }
94    }
95
96    pub fn values(&self) -> &BTreeMap<String, T> {
97        &self.values
98    }
99
100    pub fn into_values(self) -> BTreeMap<String, T> {
101        self.values
102    }
103
104    pub fn merge(&mut self, other: Self) -> BuckyResult<()> {
105        for (key, value) in other.into_values() {
106            match self.values.entry(key.clone()) {
107                Entry::Vacant(v) => {
108                    v.insert(value);
109                    self.dirty = true;
110                }
111                Entry::Occupied(_o) => {
112                    let msg = format!("merge ObjectMap with map content error! object with key already exists! key={}", key);
113                    warn!("{}", msg);
114                    return Err(BuckyError::new(BuckyErrorCode::AlreadyExists, msg));
115                }
116            }
117        }
118
119        Ok(())
120    }
121
122    pub fn list(&self, list: &mut ObjectMapContentList) -> BuckyResult<usize> {
123        let mut len = 0;
124        for (key, value) in &self.values {
125            list.push_key_value(key, value.to_owned());
126            len += 1;
127        }
128
129        Ok(len)
130    }
131
132    pub fn next(&self, it: &mut ObjectMapIterator) -> BuckyResult<()> {
133        // 读取当前的状态
134        let pos = it.current_pos().into_simple_map();
135        // info!("current pos: {:?}", pos);
136
137        let begin = match pos {
138            Some(key) => std::ops::Bound::Excluded(key),
139            None => std::ops::Bound::Unbounded,
140        };
141
142        let end = std::ops::Bound::Unbounded;
143
144        let range = self.values.range((begin, end));
145        for (key, value) in range {
146            it.push_key_value(key, value.to_owned());
147            if it.is_enough() {
148                // 当前对象还没迭代完,那么需要保存状态
149                it.update_pos(
150                    it.depth(),
151                    IteratorPosition::SimpleMap(Some(key.to_owned())),
152                );
153                break;
154            }
155        }
156
157        Ok(())
158    }
159
160    pub(crate) fn diff(&self, other: &MapContentT<T>, diff: &mut ObjectMapDiff) {
161        for (key, value) in &self.values {
162            if let Some(other_value) = other.values.get(key) {
163                if value != other_value {
164                    diff.map_alter_item(&key, value.to_owned(), other_value.to_owned());
165                }
166            } else {
167                diff.map_item(ObjectMapDiffAction::Remove, &key, value.to_owned());
168            }
169        }
170
171        for (key, value) in &other.values {
172            if let None = self.values.get(key) {
173                diff.map_item(ObjectMapDiffAction::Add, &key, value.to_owned());
174            }
175        }
176    }
177
178    // map methods
179    pub fn get_by_key(&self, key: &str) -> BuckyResult<Option<T>> {
180        match self.values.get(key) {
181            Some(v) => Ok(Some(v.to_owned())),
182            None => Ok(None),
183        }
184    }
185
186    pub fn insert_with_key(&mut self, key: &str, value: &T) -> BuckyResult<()> {
187        match self.values.entry(key.to_owned()) {
188            Entry::Vacant(v) => {
189                v.insert(value.to_owned());
190                self.dirty = true;
191                Ok(())
192            }
193            Entry::Occupied(_o) => {
194                let msg = format!("object with key already exists! key={}", key);
195                warn!("{}", msg);
196                Err(BuckyError::new(BuckyErrorCode::AlreadyExists, msg))
197            }
198        }
199    }
200
201    pub fn set_with_key(
202        &mut self,
203        key: &str,
204        value: &T,
205        prev_value: &Option<T>,
206        auto_insert: bool,
207    ) -> BuckyResult<Option<T>> {
208        match self.values.entry(key.to_owned()) {
209            Entry::Vacant(v) => {
210                if auto_insert {
211                    debug!(
212                        "set_with_key auto insert new value: key={}, value={}",
213                        key, value
214                    );
215
216                    v.insert(value.to_owned());
217                    self.dirty = true;
218                    Ok(None)
219                } else {
220                    let msg = format!("set_with_key but not found! key={}", key);
221                    warn!("{}", msg);
222                    Err(BuckyError::new(BuckyErrorCode::NotFound, msg))
223                }
224            }
225            Entry::Occupied(o) => {
226                let o = o.into_mut();
227                let old = o.clone();
228
229                // 如果指定了前一个值,那么使用CAS操作
230                if let Some(prev_value) = prev_value {
231                    if *prev_value != old {
232                        let msg = format!(
233                            "set_with_key but not match! key={}, now={}, prev={}",
234                            key, old, prev_value
235                        );
236                        warn!("{}", msg);
237                        return Err(BuckyError::new(BuckyErrorCode::Unmatch, msg));
238                    }
239                }
240
241                if *value != old {
242                    debug!("set_with_key: key={}, {} -> {}", key, old, value);
243                    *o = value.to_owned();
244                    self.dirty = true;
245                }
246
247                Ok(Some(old))
248            }
249        }
250    }
251
252    pub fn remove_with_key(&mut self, key: &str, prev_value: &Option<T>) -> BuckyResult<Option<T>> {
253        match prev_value {
254            Some(prev_value) => {
255                // 如果指定了前值,那么需要判断下
256                match self.values.get(key) {
257                    Some(current) => {
258                        if *current != *prev_value {
259                            let msg = format!(
260                                "remove_with_key but not match! key={}, now={}, prev={}",
261                                key, current, prev_value
262                            );
263                            warn!("{}", msg);
264                            return Err(BuckyError::new(BuckyErrorCode::Unmatch, msg));
265                        }
266
267                        let ret = self.values.remove(key).unwrap();
268                        self.dirty = true;
269                        Ok(Some(ret))
270                    }
271                    None => {
272                        // 如果已经不存在了,那么不需要和prev_value匹配了,直接返回成功
273                        Ok(None)
274                    }
275                }
276            }
277            None => {
278                let ret = self.values.remove(key);
279                if ret.is_some() {
280                    self.dirty = true;
281                }
282                Ok(ret)
283            }
284        }
285    }
286}
287
288#[derive(Clone, Debug, RawEncode, RawDecode)]
289pub struct SetContentT<T>
290where
291    T: Send
292        + Sync
293        + Clone
294        + Ord
295        + std::fmt::Display
296        + RawEncode
297        + IntoObjectMapContentItem
298        + From<SetIteratorPostion>,
299{
300    values: BTreeSet<T>,
301
302    #[cyfs(skip)]
303    dirty: bool,
304}
305
306impl<T> SetContentT<T>
307where
308    T: Send
309        + Sync
310        + Clone
311        + Ord
312        + std::fmt::Display
313        + RawEncode
314        + IntoObjectMapContentItem
315        + From<SetIteratorPostion>,
316    SetIteratorPostion: From<T>,
317{
318    pub fn new() -> Self {
319        Self {
320            values: BTreeSet::new(),
321            dirty: false,
322        }
323    }
324
325    pub fn values(&self) -> &BTreeSet<T> {
326        &self.values
327    }
328
329    pub fn into_values(self) -> BTreeSet<T> {
330        self.values
331    }
332
333    pub fn merge(&mut self, other: Self) -> BuckyResult<()> {
334        for value in other.into_values() {
335            match self.values.insert(value.clone()) {
336                true => {
337                    self.dirty = true;
338                    continue;
339                }
340                false => {
341                    let msg = format!(
342                        "merge ObjectMap with set content error! object already exists! value={}",
343                        value
344                    );
345                    warn!("{}", msg);
346                }
347            }
348        }
349
350        Ok(())
351    }
352
353    pub fn list(&self, list: &mut ObjectMapContentList) -> BuckyResult<usize> {
354        let mut len = 0;
355        for value in &self.values {
356            list.push_value(value.to_owned());
357            len += 1;
358        }
359
360        Ok(len)
361    }
362
363    pub fn next(&self, it: &mut ObjectMapIterator) -> BuckyResult<()> {
364        // 读取当前的状态
365        let pos = it.current_pos().into_simple_set();
366
367        let begin: std::ops::Bound<T> = match pos {
368            Some(key) => std::ops::Bound::Excluded(key.into()),
369            None => std::ops::Bound::Unbounded,
370        };
371
372        let end = std::ops::Bound::Unbounded;
373
374        let range = self.values.range((begin, end));
375        for value in range {
376            it.push_value(value.to_owned());
377            if it.is_enough() {
378                // 当前对象还没迭代完,那么需要保存状态
379                let pos = SetIteratorPostion::from(value.to_owned());
380                it.update_pos(it.depth(), IteratorPosition::SimpleSet(Some(pos)));
381                break;
382            }
383        }
384
385        Ok(())
386    }
387
388    pub(crate) fn diff(&self, other: &SetContentT<T>, diff: &mut ObjectMapDiff) {
389        for value in &self.values {
390            if let None = other.values.get(value) {
391                diff.set_item(ObjectMapDiffAction::Remove, value.to_owned());
392            }
393        }
394
395        for value in &other.values {
396            if let None = self.values.get(value) {
397                diff.set_item(ObjectMapDiffAction::Add, value.to_owned());
398            }
399        }
400    }
401
402    // set methods
403    pub fn contains(&self, value: &T) -> BuckyResult<bool> {
404        Ok(self.values.contains(value))
405    }
406
407    pub fn insert(&mut self, value: &T) -> BuckyResult<bool> {
408        let ret = self.values.insert(value.to_owned());
409        if ret {
410            self.dirty = true;
411        }
412
413        Ok(ret)
414    }
415
416    pub fn remove(&mut self, value: &T) -> BuckyResult<bool> {
417        let ret = self.values.remove(value);
418        if ret {
419            self.dirty = true;
420        }
421
422        Ok(ret)
423    }
424}
425
426type MapContent = MapContentT<ObjectId>;
427type DiffMapContent = MapContentT<ObjectMapDiffMapItem>;
428
429type SetContent = SetContentT<ObjectId>;
430type DiffSetContent = SetContentT<ObjectMapDiffSetItem>;
431
432#[derive(Clone, Debug, RawEncode, RawDecode)]
433pub enum SimpleContent {
434    Map(MapContent),
435    DiffMap(DiffMapContent),
436    Set(SetContent),
437    DiffSet(DiffSetContent),
438}
439
440impl SimpleContent {
441    pub fn content_type(&self) -> ObjectMapSimpleContentType {
442        match &self {
443            Self::Map(_) => ObjectMapSimpleContentType::Map,
444            Self::DiffMap(_) => ObjectMapSimpleContentType::DiffMap,
445            Self::Set(_) => ObjectMapSimpleContentType::Set,
446            Self::DiffSet(_) => ObjectMapSimpleContentType::DiffSet,
447        }
448    }
449
450    pub fn as_map(&self) -> &MapContent {
451        match &self {
452            Self::Map(value) => value,
453            _ => unreachable!(),
454        }
455    }
456
457    pub fn as_diff_map(&self) -> &DiffMapContent {
458        match &self {
459            Self::DiffMap(value) => value,
460            _ => unreachable!(),
461        }
462    }
463
464    pub fn as_set(&self) -> &SetContent {
465        match &self {
466            Self::Set(value) => value,
467            _ => unreachable!(),
468        }
469    }
470
471    pub fn as_diff_set(&self) -> &DiffSetContent {
472        match &self {
473            Self::DiffSet(value) => value,
474            _ => unreachable!(),
475        }
476    }
477}
478
479#[derive(Clone, Debug, RawEncode, RawDecode)]
480pub struct ObjectMapSimpleContent {
481    depth: u8,
482    content: SimpleContent,
483}
484
485impl ObjectMapSimpleContent {
486    pub fn new(content_type: ObjectMapSimpleContentType, depth: u8) -> Self {
487        let content = match content_type {
488            ObjectMapSimpleContentType::Map => SimpleContent::Map(MapContent::new()),
489            ObjectMapSimpleContentType::DiffMap => SimpleContent::DiffMap(DiffMapContent::new()),
490            ObjectMapSimpleContentType::Set => SimpleContent::Set(SetContent::new()),
491            ObjectMapSimpleContentType::DiffSet => SimpleContent::DiffSet(DiffSetContent::new()),
492        };
493
494        Self { depth, content }
495    }
496
497    pub fn content(&self) -> &SimpleContent {
498        &self.content
499    }
500
501    pub fn len(&self) -> usize {
502        match &self.content {
503            SimpleContent::Map(content) => content.values.len(),
504            SimpleContent::DiffMap(content) => content.values.len(),
505            SimpleContent::Set(content) => content.values.len(),
506            SimpleContent::DiffSet(content) => content.values.len(),
507        }
508    }
509
510    pub fn is_dirty(&self) -> bool {
511        match &self.content {
512            SimpleContent::Map(content) => content.dirty,
513            SimpleContent::DiffMap(content) => content.dirty,
514            SimpleContent::Set(content) => content.dirty,
515            SimpleContent::DiffSet(content) => content.dirty,
516        }
517    }
518
519    pub fn clear_dirty(&mut self) {
520        match &mut self.content {
521            SimpleContent::Map(content) => content.dirty = false,
522            SimpleContent::DiffMap(content) => content.dirty = false,
523            SimpleContent::Set(content) => content.dirty = false,
524            SimpleContent::DiffSet(content) => content.dirty = false,
525        }
526    }
527
528    pub fn merge(&mut self, other: Self) -> BuckyResult<()> {
529        match &mut self.content {
530            SimpleContent::Map(content) => match other.content {
531                SimpleContent::Map(other) => {
532                    content.merge(other)?;
533                }
534                _ => {
535                    let msg =
536                        format!("merge ObjectMap with map content error! unmatch content type");
537                    error!("{}", msg);
538                    return Err(BuckyError::new(BuckyErrorCode::Unmatch, msg));
539                }
540            },
541            SimpleContent::DiffMap(content) => match other.content {
542                SimpleContent::DiffMap(other) => {
543                    content.merge(other)?;
544                }
545                _ => {
546                    let msg =
547                        format!("merge ObjectMap with diffmap content error! unmatch content type");
548                    error!("{}", msg);
549                    return Err(BuckyError::new(BuckyErrorCode::Unmatch, msg));
550                }
551            },
552
553            SimpleContent::Set(content) => match other.content {
554                SimpleContent::Set(other) => {
555                    content.merge(other)?;
556                }
557                _ => {
558                    let msg =
559                        format!("merge ObjectMap with set content error! unmatch content type");
560                    error!("{}", msg);
561                    return Err(BuckyError::new(BuckyErrorCode::Unmatch, msg));
562                }
563            },
564            SimpleContent::DiffSet(content) => match other.content {
565                SimpleContent::DiffSet(other) => {
566                    content.merge(other)?;
567                }
568                _ => {
569                    let msg =
570                        format!("merge ObjectMap with diffet content error! unmatch content type");
571                    error!("{}", msg);
572                    return Err(BuckyError::new(BuckyErrorCode::Unmatch, msg));
573                }
574            },
575        }
576
577        Ok(())
578    }
579
580    // 用以对基于path的多级objectmap的支持
581    pub async fn get_or_create_child_object_map(
582        &mut self,
583        builder: &ObjectMapBuilder,
584        cache: &ObjectMapOpEnvCacheRef,
585        key: &str,
586        auto_create: ObjectMapCreateStrategy,
587        access: Option<AccessString>,
588    ) -> BuckyResult<Option<ObjectMapRef>> {
589        let ret = self.get_by_key(key)?;
590        match ret {
591            Some(sub_id) => {
592                if auto_create == ObjectMapCreateStrategy::CreateNew {
593                    let msg = format!(
594                        "objectmap solt already been taken! key={}, current={}, type={:?}",
595                        key, sub_id, sub_id.obj_type_code(),
596                    );
597                    warn!("{}", msg);
598                    return Err(BuckyError::new(BuckyErrorCode::AlreadyExists, msg));
599                }
600
601                // 如果子对象类型不是objectmap
602                if sub_id.obj_type_code() != ObjectTypeCode::ObjectMap {
603                    let msg = format!(
604                        "objectmap solt already been taken by other object! key={}, current={}, type={:?}",
605                        key, sub_id, sub_id.obj_type_code(),
606                    );
607                    warn!("{}", msg);
608                    return Err(BuckyError::new(BuckyErrorCode::AlreadyExists, msg));
609                }
610
611                // 加载对应的submap
612                let sub_map = cache.get_object_map(&sub_id).await?;
613                if sub_map.is_none() {
614                    let msg = format!(
615                        "get sub objectmap from cache but not found! key={}, id={}",
616                        key, sub_id
617                    );
618                    error!("{}", msg);
619                    return Err(BuckyError::new(BuckyErrorCode::NotFound, msg));
620                }
621
622                Ok(Some(sub_map.unwrap()))
623            }
624            None => {
625                if auto_create == ObjectMapCreateStrategy::NotCreate {
626                    return Ok(None);
627                }
628
629                // 创建新的object map
630                let sub = builder.clone().class(ObjectMapClass::Root).build();
631                let sub_id = sub.flush_id();
632                if let Err(e) = self.insert_with_key(key, &sub_id) {
633                    let msg = format!("insert object map with key={} error! {}", key, e);
634                    error!("{}", msg);
635                    return Err(BuckyError::new(e.code(), msg));
636                }
637
638                debug!("object map new sub: key={}, sub={}", key, sub_id);
639                let sub_map = cache.put_object_map(&sub_id, sub, access)?;
640                Ok(Some(sub_map))
641            }
642        }
643    }
644
645    pub fn list(&self, list: &mut ObjectMapContentList) -> BuckyResult<usize> {
646        match &self.content {
647            SimpleContent::Map(content) => content.list(list),
648            SimpleContent::DiffMap(content) => content.list(list),
649            SimpleContent::Set(content) => content.list(list),
650            SimpleContent::DiffSet(content) => content.list(list),
651        }
652    }
653
654    pub fn next(&self, it: &mut ObjectMapIterator) -> BuckyResult<()> {
655        match &self.content {
656            SimpleContent::Map(content) => content.next(it),
657            SimpleContent::DiffMap(content) => content.next(it),
658            SimpleContent::Set(content) => content.next(it),
659            SimpleContent::DiffSet(content) => content.next(it),
660        }
661    }
662
663    pub(crate) fn diff(&self, other: &Self, diff: &mut ObjectMapDiff) {
664        match &self.content {
665            SimpleContent::Map(content) => content.diff(other.content.as_map(), diff),
666            SimpleContent::DiffMap(content) => content.diff(other.content.as_diff_map(), diff),
667            SimpleContent::Set(content) => content.diff(other.content.as_set(), diff),
668            SimpleContent::DiffSet(content) => content.diff(other.content.as_diff_set(), diff),
669        }
670    }
671
672    // visitor
673    pub(crate) async fn visit(&self, visitor: &mut impl ObjectMapVisitor) -> BuckyResult<()> {
674        match &self.content {
675            SimpleContent::Map(content) => {
676                for (key, value) in &content.values {
677                    visitor.visit_map_item(&key, value).await?;
678                }
679            }
680            SimpleContent::DiffMap(content) => {
681                for (key, value) in &content.values {
682                    visitor.visit_diff_map_item(&key, value).await?;
683                }
684            }
685            SimpleContent::Set(content) => {
686                for value in &content.values {
687                    visitor.visit_set_item(value).await?;
688                }
689            }
690            SimpleContent::DiffSet(content) => {
691                for value in &content.values {
692                    visitor.visit_diff_set_item(value).await?;
693                }
694            }
695        }
696
697        Ok(())
698    }
699
700    // map methods
701    pub fn get_by_key(&self, key: &str) -> BuckyResult<Option<ObjectId>> {
702        match &self.content {
703            SimpleContent::Map(content) => content.get_by_key(key),
704            _ => {
705                let msg = format!(
706                    "unmatch objectmap content type: {:?}, key={}",
707                    self.content.content_type(),
708                    key
709                );
710                warn!("{}", msg);
711
712                Err(BuckyError::new(BuckyErrorCode::NotSupport, msg))
713            }
714        }
715    }
716
717    pub fn insert_with_key(&mut self, key: &str, value: &ObjectId) -> BuckyResult<()> {
718        match &mut self.content {
719            SimpleContent::Map(content) => content.insert_with_key(key, value),
720            _ => {
721                let msg = format!(
722                    "unmatch objectmap content type: {:?}, key={}",
723                    self.content.content_type(),
724                    key
725                );
726                warn!("{}", msg);
727
728                Err(BuckyError::new(BuckyErrorCode::NotSupport, msg))
729            }
730        }
731    }
732
733    pub fn set_with_key(
734        &mut self,
735        key: &str,
736        value: &ObjectId,
737        prev_value: &Option<ObjectId>,
738        auto_insert: bool,
739    ) -> BuckyResult<Option<ObjectId>> {
740        match &mut self.content {
741            SimpleContent::Map(content) => {
742                content.set_with_key(key, value, prev_value, auto_insert)
743            }
744            _ => {
745                let msg = format!(
746                    "unmatch objectmap content type: {:?}, key={}",
747                    self.content.content_type(),
748                    key
749                );
750                warn!("{}", msg);
751
752                Err(BuckyError::new(BuckyErrorCode::NotSupport, msg))
753            }
754        }
755    }
756
757    pub fn remove_with_key(
758        &mut self,
759        key: &str,
760        prev_value: &Option<ObjectId>,
761    ) -> BuckyResult<Option<ObjectId>> {
762        match &mut self.content {
763            SimpleContent::Map(content) => content.remove_with_key(key, prev_value),
764            _ => {
765                let msg = format!(
766                    "unmatch objectmap content type: {:?}, key={}",
767                    self.content.content_type(),
768                    key
769                );
770                warn!("{}", msg);
771
772                Err(BuckyError::new(BuckyErrorCode::NotSupport, msg))
773            }
774        }
775    }
776
777    // diffmap methods
778    pub fn diff_get_by_key(&self, key: &str) -> BuckyResult<Option<ObjectMapDiffMapItem>> {
779        match &self.content {
780            SimpleContent::DiffMap(content) => content.get_by_key(key),
781            _ => {
782                let msg = format!(
783                    "unmatch objectmap content type: {:?}, key={}",
784                    self.content.content_type(),
785                    key
786                );
787                warn!("{}", msg);
788
789                Err(BuckyError::new(BuckyErrorCode::NotSupport, msg))
790            }
791        }
792    }
793
794    pub fn diff_insert_with_key(
795        &mut self,
796        key: &str,
797        value: &ObjectMapDiffMapItem,
798    ) -> BuckyResult<()> {
799        match &mut self.content {
800            SimpleContent::DiffMap(content) => content.insert_with_key(key, value),
801            _ => {
802                let msg = format!(
803                    "unmatch objectmap content type: {:?}, key={}",
804                    self.content.content_type(),
805                    key
806                );
807                warn!("{}", msg);
808
809                Err(BuckyError::new(BuckyErrorCode::NotSupport, msg))
810            }
811        }
812    }
813
814    pub fn diff_set_with_key(
815        &mut self,
816        key: &str,
817        value: &ObjectMapDiffMapItem,
818        prev_value: &Option<ObjectMapDiffMapItem>,
819        auto_insert: bool,
820    ) -> BuckyResult<Option<ObjectMapDiffMapItem>> {
821        match &mut self.content {
822            SimpleContent::DiffMap(content) => {
823                content.set_with_key(key, value, prev_value, auto_insert)
824            }
825            _ => {
826                let msg = format!(
827                    "unmatch objectmap content type: {:?}, key={}",
828                    self.content.content_type(),
829                    key
830                );
831                warn!("{}", msg);
832
833                Err(BuckyError::new(BuckyErrorCode::NotSupport, msg))
834            }
835        }
836    }
837
838    pub fn diff_remove_with_key(
839        &mut self,
840        key: &str,
841        prev_value: &Option<ObjectMapDiffMapItem>,
842    ) -> BuckyResult<Option<ObjectMapDiffMapItem>> {
843        match &mut self.content {
844            SimpleContent::DiffMap(content) => content.remove_with_key(key, prev_value),
845            _ => {
846                let msg = format!(
847                    "unmatch objectmap content type: {:?}, key={}",
848                    self.content.content_type(),
849                    key
850                );
851                warn!("{}", msg);
852
853                Err(BuckyError::new(BuckyErrorCode::NotSupport, msg))
854            }
855        }
856    }
857
858    // set methods
859    pub fn contains(&self, object_id: &ObjectId) -> BuckyResult<bool> {
860        match &self.content {
861            SimpleContent::Set(content) => content.contains(object_id),
862            _ => {
863                let msg = format!(
864                    "unmatch objectmap content type: {:?}, object={}",
865                    self.content.content_type(),
866                    object_id,
867                );
868                warn!("{}", msg);
869
870                Err(BuckyError::new(BuckyErrorCode::NotSupport, msg))
871            }
872        }
873    }
874
875    pub fn insert(&mut self, object_id: &ObjectId) -> BuckyResult<bool> {
876        match &mut self.content {
877            SimpleContent::Set(content) => content.insert(object_id),
878            _ => {
879                let msg = format!(
880                    "unmatch objectmap content type: {:?}, object={}",
881                    self.content.content_type(),
882                    object_id,
883                );
884                warn!("{}", msg);
885
886                Err(BuckyError::new(BuckyErrorCode::NotSupport, msg))
887            }
888        }
889    }
890
891    pub fn remove(&mut self, object_id: &ObjectId) -> BuckyResult<bool> {
892        match &mut self.content {
893            SimpleContent::Set(content) => content.remove(object_id),
894            _ => {
895                let msg = format!(
896                    "unmatch objectmap content type: {:?}, object={}",
897                    self.content.content_type(),
898                    object_id,
899                );
900                warn!("{}", msg);
901
902                Err(BuckyError::new(BuckyErrorCode::NotSupport, msg))
903            }
904        }
905    }
906
907    // diff set methods
908    pub fn diff_contains(&self, object_id: &ObjectMapDiffSetItem) -> BuckyResult<bool> {
909        match &self.content {
910            SimpleContent::DiffSet(content) => content.contains(object_id),
911            _ => {
912                let msg = format!(
913                    "unmatch objectmap content type: {:?}, object={}",
914                    self.content.content_type(),
915                    object_id,
916                );
917                warn!("{}", msg);
918
919                Err(BuckyError::new(BuckyErrorCode::NotSupport, msg))
920            }
921        }
922    }
923
924    pub fn diff_insert(&mut self, object_id: &ObjectMapDiffSetItem) -> BuckyResult<bool> {
925        match &mut self.content {
926            SimpleContent::DiffSet(content) => content.insert(object_id),
927            _ => {
928                let msg = format!(
929                    "unmatch objectmap content type: {:?}, object={}",
930                    self.content.content_type(),
931                    object_id,
932                );
933                warn!("{}", msg);
934
935                Err(BuckyError::new(BuckyErrorCode::NotSupport, msg))
936            }
937        }
938    }
939
940    pub fn diff_remove(&mut self, object_id: &ObjectMapDiffSetItem) -> BuckyResult<bool> {
941        match &mut self.content {
942            SimpleContent::DiffSet(content) => content.remove(object_id),
943            _ => {
944                let msg = format!(
945                    "unmatch objectmap content type: {:?}, object={}",
946                    self.content.content_type(),
947                    object_id,
948                );
949                warn!("{}", msg);
950
951                Err(BuckyError::new(BuckyErrorCode::NotSupport, msg))
952            }
953        }
954    }
955}
956
957#[derive(Clone, Debug, RawEncode, RawDecode, Serialize)]
958pub struct ObjectMapHubItem {
959    id: ObjectId,
960}
961
962#[derive(Clone, Debug, RawEncode, RawDecode)]
963pub struct ObjectMapHubContent {
964    depth: u8,
965    subs: BTreeMap<u16, ObjectMapHubItem>,
966
967    #[cyfs(skip)]
968    dirty: bool,
969}
970
971impl ObjectMapHubContent {
972    pub fn new(depth: u8) -> Self {
973        Self {
974            depth,
975            subs: BTreeMap::new(),
976            dirty: false,
977        }
978    }
979
980    pub fn subs(&self) -> &BTreeMap<u16, ObjectMapHubItem> {
981        &self.subs
982    }
983
984    pub fn is_dirty(&self) -> bool {
985        self.dirty
986    }
987
988    pub fn clear_dirty(&mut self) {
989        self.dirty = false;
990    }
991
992    fn hash_bytes(&self, key: &[u8]) -> u16 {
993        use std::collections::hash_map::DefaultHasher;
994        use std::hash::Hasher;
995
996        let mut hasher = DefaultHasher::new();
997        let mut sha256 = sha2::Sha256::new();
998        sha256.input(key);
999        sha256.input([self.depth]);
1000        hasher.write(&sha256.result());
1001        let index = (hasher.finish() % SUB_LIST_CONST_LENGTH) as u16;
1002
1003        /*
1004        let s = String::from_utf8(key.to_vec()).unwrap();
1005        trace!(
1006            "hash sub index: depth={}, key={}, index={}",
1007            self.depth,
1008            s,
1009            index
1010        );
1011        */
1012
1013        index
1014    }
1015
1016    async fn get_sub(
1017        &self,
1018        cache: &ObjectMapOpEnvCacheRef,
1019        key: &[u8],
1020    ) -> BuckyResult<Option<ObjectMapRef>> {
1021        let index = self.hash_bytes(key);
1022        match self.subs.get(&index) {
1023            Some(sub) => cache.get_object_map(&sub.id).await,
1024            None => Ok(None),
1025        }
1026    }
1027
1028    async fn get_sub_mut(
1029        &mut self,
1030        builder: Option<&ObjectMapBuilder>,
1031        cache: &ObjectMapOpEnvCacheRef,
1032        key: &[u8],
1033        auto_create: bool,
1034    ) -> BuckyResult<Option<(&mut ObjectMapHubItem, ObjectMap)>> {
1035        let index = self.hash_bytes(key);
1036        match self.subs.entry(index) {
1037            Entry::Occupied(o) => {
1038                let sub = o.into_mut();
1039                match cache.get_object_map(&sub.id).await? {
1040                    Some(item) => Ok(Some((sub, item.lock().await.clone()))),
1041                    None => {
1042                        let msg = format!("objectmap sub item exists but load from noc not found! sub={}, key={:?}, index={}", sub.id, key, index);
1043                        error!("{}", msg);
1044                        Err(BuckyError::new(BuckyErrorCode::NotFound, msg))
1045                    }
1046                }
1047            }
1048            Entry::Vacant(v) => {
1049                if auto_create {
1050                    // 创建子对象
1051                    let builder = builder.unwrap().clone().class(ObjectMapClass::Sub);
1052                    let sub = builder.build();
1053                    let id = sub.flush_id();
1054
1055                    let item = ObjectMapHubItem { id };
1056                    let solt = v.insert(item);
1057                    self.dirty = true;
1058
1059                    // 这里不再进行一次空map的保存,外部在操作完毕后需要调用put来保存
1060                    // let sub = cache.put_object_map(sub)?;
1061                    Ok(Some((solt, sub)))
1062                } else {
1063                    Ok(None)
1064                }
1065            }
1066        }
1067    }
1068
1069    fn remove_sub(&mut self, _cache: &ObjectMapOpEnvCacheRef, key: &[u8]) -> Option<ObjectId> {
1070        let index = self.hash_bytes(key);
1071        match self.subs.remove(&index) {
1072            Some(sub) => Some(sub.id),
1073            None => None,
1074        }
1075    }
1076
1077    // 目前id都是实时计算
1078
1079    // path methods
1080    #[async_recursion::async_recursion]
1081    pub async fn get_or_create_child_object_map(
1082        &mut self,
1083        builder: &ObjectMapBuilder,
1084        cache: &ObjectMapOpEnvCacheRef,
1085        key: &str,
1086        auto_create: ObjectMapCreateStrategy,
1087        access: Option<AccessString>,
1088    ) -> BuckyResult<Option<ObjectMapRef>> {
1089        let sub_auto_create = match auto_create {
1090            ObjectMapCreateStrategy::NotCreate => false,
1091            _ => true,
1092        };
1093
1094        let sub = self
1095            .get_sub_mut(Some(builder), cache, key.as_bytes(), sub_auto_create)
1096            .await?;
1097        match sub {
1098            Some((solt, mut obj_map)) => {
1099                // 复制后修改
1100                let ret = obj_map
1101                    .get_or_create_child_object_map(cache, key, builder.content_type(), auto_create, access)
1102                    .await?;
1103                let current_id = obj_map.cached_object_id();
1104                let new_id = obj_map.flush_id();
1105
1106                // 只有objectmap的id改变了,才需要保存并更新
1107                if current_id != Some(new_id) {
1108                    cache.put_object_map(&new_id, obj_map, None)?;
1109                    solt.id = new_id;
1110                    self.dirty = true;
1111                }
1112                Ok(ret)
1113            }
1114            None => Ok(None),
1115        }
1116    }
1117
1118    #[async_recursion::async_recursion]
1119    pub async fn list(
1120        &self,
1121        cache: &ObjectMapOpEnvCacheRef,
1122        list: &mut ObjectMapContentList,
1123    ) -> BuckyResult<u64> {
1124        let mut total: u64 = 0;
1125        for (_key, sub) in &self.subs {
1126            let sub_map = cache.get_object_map(&sub.id).await?;
1127            if sub_map.is_none() {
1128                let msg = format!(
1129                    "read objectmap to list but sub item not found: id={}",
1130                    sub.id
1131                );
1132                error!("{}", msg);
1133                return Err(BuckyError::new(BuckyErrorCode::NotFound, msg));
1134            }
1135            let sub_map = sub_map.unwrap();
1136            let obj = sub_map.lock().await;
1137            total += obj.list(cache, list).await? as u64;
1138        }
1139
1140        Ok(total)
1141    }
1142
1143    #[async_recursion::async_recursion]
1144    pub async fn list_subs(
1145        &self,
1146        cache: &ObjectMapOpEnvCacheRef,
1147        list: &mut Vec<ObjectId>,
1148    ) -> BuckyResult<u64> {
1149        let mut total: u64 = 0;
1150        for (_key, sub) in &self.subs {
1151            list.push(sub.id.clone());
1152
1153            let sub_map = cache.get_object_map(&sub.id).await?;
1154            if sub_map.is_none() {
1155                let msg = format!(
1156                    "read objectmap to list but sub item not found: id={}",
1157                    sub.id
1158                );
1159                error!("{}", msg);
1160                return Err(BuckyError::new(BuckyErrorCode::NotFound, msg));
1161            }
1162            let sub_map = sub_map.unwrap();
1163            let obj = sub_map.lock().await;
1164            total += obj.list_subs(cache, list).await? as u64;
1165        }
1166
1167        Ok(total)
1168    }
1169
1170    #[async_recursion::async_recursion]
1171    pub async fn next(&self, it: &mut ObjectMapIterator) -> BuckyResult<()> {
1172        // 读取当前的状态
1173        let pos = it.current_pos().into_hub();
1174        let depth = it.depth();
1175
1176        let begin = match pos {
1177            Some(key) => std::ops::Bound::Included(key),
1178            None => std::ops::Bound::Unbounded,
1179        };
1180
1181        let end = std::ops::Bound::Unbounded;
1182
1183        let range = self.subs.range((begin, end));
1184        for (key, sub) in range {
1185            let sub_map = it.cache.get_object_map(&sub.id).await?;
1186            if sub_map.is_none() {
1187                let msg = format!(
1188                    "load sub object map from cache but not found! id={}",
1189                    sub.id
1190                );
1191                error!("{}", msg);
1192                return Err(BuckyError::new(BuckyErrorCode::NotFound, msg));
1193            }
1194            let sub_map = sub_map.unwrap();
1195            {
1196                let obj = sub_map.lock().await;
1197                it.inc_depth(obj.mode(), obj.content_type());
1198
1199                obj.next(it).await?;
1200            }
1201            if it.is_enough() {
1202                // 当前对象还没迭代完,那么需要保存状态
1203                it.update_pos(depth, IteratorPosition::Hub(Some(key.to_owned())));
1204
1205                return Ok(());
1206            }
1207
1208            // 继续下一个sub
1209            it.dec_depth();
1210        }
1211
1212        assert!(!it.is_enough());
1213
1214        Ok(())
1215    }
1216
1217    pub(crate) fn diff(&self, other: &Self, diff: &mut ObjectMapDiff) {
1218        for (key, value) in &self.subs {
1219            if let Some(other_value) = other.subs.get(key) {
1220                if value.id != other_value.id {
1221                    diff.pend_async_sub_alter(&value.id, &other_value.id);
1222                }
1223            } else {
1224                diff.pend_async_remove(&value.id);
1225            }
1226        }
1227
1228        for (key, value) in &other.subs {
1229            if let None = self.subs.get(key) {
1230                diff.pend_async_add(&value.id);
1231            }
1232        }
1233    }
1234
1235    // visitor
1236    pub async fn visit(&self, visitor: &mut impl ObjectMapVisitor) -> BuckyResult<()> {
1237        for (_key, value) in &self.subs {
1238            visitor.visit_hub_item(&value.id).await?;
1239        }
1240
1241        Ok(())
1242    }
1243
1244    // map methods
1245    #[async_recursion::async_recursion]
1246    pub async fn get_by_key(
1247        &self,
1248        cache: &ObjectMapOpEnvCacheRef,
1249        key: &str,
1250    ) -> BuckyResult<Option<ObjectId>> {
1251        let sub = self.get_sub(cache, key.as_bytes()).await?;
1252        match sub {
1253            Some(sub) => {
1254                let obj_map = sub.lock().await;
1255                obj_map.get_by_key(cache, key).await
1256            }
1257            None => Ok(None),
1258        }
1259    }
1260
1261    #[async_recursion::async_recursion]
1262    pub async fn insert_with_key(
1263        &mut self,
1264        builder: &ObjectMapBuilder,
1265        cache: &ObjectMapOpEnvCacheRef,
1266        key: &str,
1267        value: &ObjectId,
1268    ) -> BuckyResult<()> {
1269        let sub = self
1270            .get_sub_mut(Some(builder), cache, key.as_bytes(), true)
1271            .await?;
1272        match sub {
1273            Some((solt, mut obj_map)) => {
1274                obj_map.insert_with_key(&cache, &key, &value).await?;
1275
1276                let new_id = obj_map.flush_id();
1277                // debug!("insert_with_key, sub objectmap updated: key={}, {:?} -> {}", key, obj_map.cached_object_id(), new_id);
1278                cache.put_object_map(&new_id, obj_map, None)?;
1279                solt.id = new_id;
1280                self.dirty = true;
1281                Ok(())
1282            }
1283            None => {
1284                unreachable!();
1285            }
1286        }
1287    }
1288
1289    #[async_recursion::async_recursion]
1290    pub async fn set_with_key(
1291        &mut self,
1292        builder: &ObjectMapBuilder,
1293        cache: &ObjectMapOpEnvCacheRef,
1294        key: &str,
1295        value: &ObjectId,
1296        prev_value: &Option<ObjectId>,
1297        auto_insert: bool,
1298    ) -> BuckyResult<Option<ObjectId>> {
1299        let sub = self
1300            .get_sub_mut(Some(builder), cache, key.as_bytes(), true)
1301            .await?;
1302        match sub {
1303            Some((solt, mut obj_map)) => {
1304                let ret = obj_map
1305                    .set_with_key(cache, key, value, prev_value, auto_insert)
1306                    .await?;
1307                let current_id = obj_map.cached_object_id();
1308                let new_id = obj_map.flush_id();
1309                if current_id != Some(new_id) {
1310                    cache.put_object_map(&new_id, obj_map, None)?;
1311                    solt.id = new_id;
1312                    self.dirty = true;
1313                }
1314                Ok(ret)
1315            }
1316            None => {
1317                unreachable!();
1318            }
1319        }
1320    }
1321
1322    #[async_recursion::async_recursion]
1323    pub async fn remove_with_key(
1324        &mut self,
1325        cache: &ObjectMapOpEnvCacheRef,
1326        key: &str,
1327        prev_value: &Option<ObjectId>,
1328    ) -> BuckyResult<Option<ObjectId>> {
1329        let sub = self.get_sub_mut(None, cache, key.as_bytes(), false).await?;
1330        match sub {
1331            Some((solt, mut obj_map)) => {
1332                let ret = obj_map.remove_with_key(cache, key, prev_value).await?;
1333
1334                if ret.is_some() {
1335                    if obj_map.count() > 0 {
1336                        let new_id = obj_map.flush_id();
1337                        cache.put_object_map(&new_id, obj_map, None)?;
1338                        solt.id = new_id;
1339                    } else {
1340                        debug!(
1341                            "sub objectmap is empty! now will remove: key={}, sub={}",
1342                            key, solt.id
1343                        );
1344                        let sub_id = solt.id.clone();
1345                        drop(solt);
1346                        drop(obj_map);
1347
1348                        let ret = self.remove_sub(cache, key.as_bytes());
1349                        assert_eq!(ret, Some(sub_id));
1350                    }
1351                    self.dirty = true;
1352                }
1353                Ok(ret)
1354            }
1355            None => {
1356                unreachable!();
1357            }
1358        }
1359    }
1360
1361    // diff map methods
1362    #[async_recursion::async_recursion]
1363    pub async fn diff_get_by_key(
1364        &self,
1365        cache: &ObjectMapOpEnvCacheRef,
1366        key: &str,
1367    ) -> BuckyResult<Option<ObjectMapDiffMapItem>> {
1368        let sub = self.get_sub(cache, key.as_bytes()).await?;
1369        match sub {
1370            Some(sub) => {
1371                let obj_map = sub.lock().await;
1372                obj_map.diff_get_by_key(cache, key).await
1373            }
1374            None => Ok(None),
1375        }
1376    }
1377
1378    #[async_recursion::async_recursion]
1379    pub async fn diff_insert_with_key(
1380        &mut self,
1381        builder: &ObjectMapBuilder,
1382        cache: &ObjectMapOpEnvCacheRef,
1383        key: &str,
1384        value: &ObjectMapDiffMapItem,
1385    ) -> BuckyResult<()> {
1386        let sub = self
1387            .get_sub_mut(Some(builder), cache, key.as_bytes(), true)
1388            .await?;
1389        match sub {
1390            Some((solt, mut obj_map)) => {
1391                obj_map.diff_insert_with_key(&cache, &key, &value).await?;
1392
1393                let new_id = obj_map.flush_id();
1394                // debug!("insert_with_key, sub objectmap updated: key={}, {:?} -> {}", key, obj_map.cached_object_id(), new_id);
1395                cache.put_object_map(&new_id, obj_map, None)?;
1396                solt.id = new_id;
1397                self.dirty = true;
1398                Ok(())
1399            }
1400            None => {
1401                unreachable!();
1402            }
1403        }
1404    }
1405
1406    #[async_recursion::async_recursion]
1407    pub async fn diff_set_with_key(
1408        &mut self,
1409        builder: &ObjectMapBuilder,
1410        cache: &ObjectMapOpEnvCacheRef,
1411        key: &str,
1412        value: &ObjectMapDiffMapItem,
1413        prev_value: &Option<ObjectMapDiffMapItem>,
1414        auto_insert: bool,
1415    ) -> BuckyResult<Option<ObjectMapDiffMapItem>> {
1416        let sub = self
1417            .get_sub_mut(Some(builder), cache, key.as_bytes(), true)
1418            .await?;
1419        match sub {
1420            Some((solt, mut obj_map)) => {
1421                let ret = obj_map
1422                    .diff_set_with_key(cache, key, value, prev_value, auto_insert)
1423                    .await?;
1424                let current_id = obj_map.cached_object_id();
1425                let new_id = obj_map.flush_id();
1426                if current_id != Some(new_id) {
1427                    cache.put_object_map(&new_id, obj_map, None)?;
1428                    solt.id = new_id;
1429                    self.dirty = true;
1430                }
1431                Ok(ret)
1432            }
1433            None => {
1434                unreachable!();
1435            }
1436        }
1437    }
1438
1439    #[async_recursion::async_recursion]
1440    pub async fn diff_remove_with_key(
1441        &mut self,
1442        cache: &ObjectMapOpEnvCacheRef,
1443        key: &str,
1444        prev_value: &Option<ObjectMapDiffMapItem>,
1445    ) -> BuckyResult<Option<ObjectMapDiffMapItem>> {
1446        let sub = self.get_sub_mut(None, cache, key.as_bytes(), false).await?;
1447        match sub {
1448            Some((solt, mut obj_map)) => {
1449                let ret = obj_map.diff_remove_with_key(cache, key, prev_value).await?;
1450
1451                if ret.is_some() {
1452                    if obj_map.count() > 0 {
1453                        let new_id = obj_map.flush_id();
1454                        cache.put_object_map(&new_id, obj_map, None)?;
1455                        solt.id = new_id;
1456                    } else {
1457                        debug!(
1458                            "sub objectmap is empty! now will remove: key={}, sub={}",
1459                            key, solt.id
1460                        );
1461                        let sub_id = solt.id.clone();
1462                        drop(solt);
1463                        drop(obj_map);
1464
1465                        let ret = self.remove_sub(cache, key.as_bytes());
1466                        assert_eq!(ret, Some(sub_id));
1467                    }
1468                    self.dirty = true;
1469                }
1470                Ok(ret)
1471            }
1472            None => {
1473                unreachable!();
1474            }
1475        }
1476    }
1477
1478    // set methods
1479    #[async_recursion::async_recursion]
1480    pub async fn contains(
1481        &self,
1482        cache: &ObjectMapOpEnvCacheRef,
1483        object_id: &ObjectId,
1484    ) -> BuckyResult<bool> {
1485        let sub = self.get_sub(cache, object_id.as_ref().as_slice()).await?;
1486        match sub {
1487            Some(sub) => {
1488                let obj_map = sub.lock().await;
1489                obj_map.contains(cache, object_id).await
1490            }
1491            None => Ok(false),
1492        }
1493    }
1494
1495    #[async_recursion::async_recursion]
1496    pub async fn insert(
1497        &mut self,
1498        builder: &ObjectMapBuilder,
1499        cache: &ObjectMapOpEnvCacheRef,
1500        object_id: &ObjectId,
1501    ) -> BuckyResult<bool> {
1502        let sub = self
1503            .get_sub_mut(Some(builder), cache, object_id.as_ref().as_slice(), true)
1504            .await?;
1505        match sub {
1506            Some((solt, mut obj_map)) => {
1507                let ret = obj_map.insert(cache, object_id).await?;
1508                if ret {
1509                    let new_id = obj_map.flush_id();
1510                    cache.put_object_map(&new_id, obj_map, None)?;
1511                    solt.id = new_id;
1512                    self.dirty = true;
1513                }
1514
1515                Ok(ret)
1516            }
1517            None => {
1518                unreachable!();
1519            }
1520        }
1521    }
1522
1523    #[async_recursion::async_recursion]
1524    pub async fn remove(
1525        &mut self,
1526        cache: &ObjectMapOpEnvCacheRef,
1527        object_id: &ObjectId,
1528    ) -> BuckyResult<bool> {
1529        let sub = self
1530            .get_sub_mut(None, cache, object_id.as_ref().as_slice(), false)
1531            .await?;
1532        match sub {
1533            Some((solt, mut obj_map)) => {
1534                let ret = obj_map.remove(cache, object_id).await?;
1535                if ret {
1536                    if obj_map.count() > 0 {
1537                        let new_id = obj_map.flush_id();
1538                        cache.put_object_map(&new_id, obj_map, None)?;
1539                        solt.id = new_id;
1540                    } else {
1541                        debug!(
1542                            "sub objectmap is empty! now will remove: value={}, sub={}",
1543                            object_id, solt.id
1544                        );
1545                        drop(solt);
1546                        drop(obj_map);
1547
1548                        let _ret = self.remove_sub(cache, object_id.as_ref().as_slice());
1549                    }
1550                    self.dirty = true;
1551                }
1552
1553                Ok(ret)
1554            }
1555            None => {
1556                let msg = format!(
1557                    "remove object from objectmap with set content but sub obj not found! object={}",
1558                    object_id
1559                );
1560                warn!("{}", msg);
1561
1562                Err(BuckyError::new(BuckyErrorCode::NotFound, msg))
1563            }
1564        }
1565    }
1566
1567    // diff set methods
1568    #[async_recursion::async_recursion]
1569    pub async fn diff_contains(
1570        &self,
1571        cache: &ObjectMapOpEnvCacheRef,
1572        object_id: &ObjectMapDiffSetItem,
1573    ) -> BuckyResult<bool> {
1574        let sub = self.get_sub(cache, object_id.as_slice()).await?;
1575        match sub {
1576            Some(sub) => {
1577                let obj_map = sub.lock().await;
1578                obj_map.diff_contains(cache, object_id).await
1579            }
1580            None => Ok(false),
1581        }
1582    }
1583
1584    #[async_recursion::async_recursion]
1585    pub async fn diff_insert(
1586        &mut self,
1587        builder: &ObjectMapBuilder,
1588        cache: &ObjectMapOpEnvCacheRef,
1589        object_id: &ObjectMapDiffSetItem,
1590    ) -> BuckyResult<bool> {
1591        let sub = self
1592            .get_sub_mut(Some(builder), cache, object_id.as_slice(), true)
1593            .await?;
1594        match sub {
1595            Some((solt, mut obj_map)) => {
1596                let ret = obj_map.diff_insert(cache, object_id).await?;
1597                if ret {
1598                    let new_id = obj_map.flush_id();
1599                    cache.put_object_map(&new_id, obj_map, None)?;
1600                    solt.id = new_id;
1601                    self.dirty = true;
1602                }
1603
1604                Ok(ret)
1605            }
1606            None => {
1607                unreachable!();
1608            }
1609        }
1610    }
1611
1612    #[async_recursion::async_recursion]
1613    pub async fn diff_remove(
1614        &mut self,
1615        cache: &ObjectMapOpEnvCacheRef,
1616        object_id: &ObjectMapDiffSetItem,
1617    ) -> BuckyResult<bool> {
1618        let sub = self
1619            .get_sub_mut(None, cache, object_id.as_slice(), false)
1620            .await?;
1621        match sub {
1622            Some((solt, mut obj_map)) => {
1623                let ret = obj_map.diff_remove(cache, object_id).await?;
1624                if ret {
1625                    if obj_map.count() > 0 {
1626                        let new_id = obj_map.flush_id();
1627                        cache.put_object_map(&new_id, obj_map, None)?;
1628                        solt.id = new_id;
1629                    } else {
1630                        debug!(
1631                            "sub objectmap is empty! now will remove: value={}, sub={}",
1632                            object_id, solt.id
1633                        );
1634                        drop(solt);
1635                        drop(obj_map);
1636
1637                        let _ret = self.remove_sub(cache, object_id.as_slice());
1638                    }
1639                    self.dirty = true;
1640                }
1641
1642                Ok(ret)
1643            }
1644            None => {
1645                let msg = format!(
1646                    "remove object from objectmap with set content but sub obj not found! object={}",
1647                    object_id
1648                );
1649                warn!("{}", msg);
1650
1651                Err(BuckyError::new(BuckyErrorCode::NotFound, msg))
1652            }
1653        }
1654    }
1655}
1656
1657#[derive(Clone, Debug, Copy, RawEncode, RawDecode, Eq, PartialEq)]
1658pub enum ObjectMapSimpleContentType {
1659    Map,
1660    DiffMap,
1661    Set,
1662    DiffSet,
1663}
1664
1665impl ObjectMapSimpleContentType {
1666    pub fn get_diff_type(&self) -> Option<ObjectMapSimpleContentType> {
1667        match &self {
1668            Self::Map => Some(Self::DiffMap),
1669            Self::Set => Some(Self::DiffSet),
1670            _ => {
1671                // 目前diffmap和diffset不再支持diff操作
1672                None
1673            }
1674        }
1675    }
1676
1677    pub fn is_diff_match(&self, diff_content_type: &Self) -> bool {
1678        match self.get_diff_type() {
1679            Some(diff_type) => diff_type == *diff_content_type,
1680            None => false,
1681        }
1682    }
1683
1684    pub fn as_str(&self) -> &str {
1685        match self {
1686            Self::Map => "map",
1687            Self::DiffMap => "diffmap",
1688            Self::Set => "set",
1689            Self::DiffSet => "diffset",
1690        }
1691    }
1692
1693    pub fn is_map(&self) -> bool {
1694        match self {
1695            Self::Map => true,
1696            _ => false,
1697        }
1698    }
1699
1700    pub fn is_set(&self) -> bool {
1701        match self {
1702            Self::Set => true,
1703            _ => false,
1704        }
1705    }
1706}
1707
1708impl ToString for ObjectMapSimpleContentType {
1709    fn to_string(&self) -> String {
1710        self.as_str().to_owned()
1711    }
1712}
1713
1714impl std::str::FromStr for ObjectMapSimpleContentType {
1715    type Err = BuckyError;
1716
1717    fn from_str(value: &str) -> Result<Self, Self::Err> {
1718        let ret = match value {
1719            "map" => Self::Map,
1720            "diffmap" => Self::DiffMap,
1721            "set" => Self::Set,
1722            "diffset" => Self::DiffSet,
1723
1724            v @ _ => {
1725                let msg = format!("unknown simple content type: {}", v);
1726                error!("{}", msg);
1727
1728                return Err(BuckyError::new(BuckyErrorCode::InvalidData, msg));
1729            }
1730        };
1731
1732        Ok(ret)
1733    }
1734}
1735
1736#[derive(Debug, Clone, Copy, Eq, PartialEq)]
1737pub enum ObjectMapContentMode {
1738    Simple,
1739    Hub,
1740}
1741
1742impl ToString for ObjectMapContentMode {
1743    fn to_string(&self) -> String {
1744        match *self {
1745            Self::Simple => "simple",
1746            Self::Hub => "hub",
1747        }
1748        .to_owned()
1749    }
1750}
1751
1752impl std::str::FromStr for ObjectMapContentMode {
1753    type Err = BuckyError;
1754
1755    fn from_str(value: &str) -> Result<Self, Self::Err> {
1756        let ret = match value {
1757            "simple" => Self::Simple,
1758            "hub" => Self::Hub,
1759
1760            v @ _ => {
1761                let msg = format!("unknown ObjectMapContentMode value: {}", v);
1762                error!("{}", msg);
1763
1764                return Err(BuckyError::new(BuckyErrorCode::InvalidData, msg));
1765            }
1766        };
1767
1768        Ok(ret)
1769    }
1770}
1771
1772#[derive(Clone, Debug, RawEncode, RawDecode)]
1773pub enum ObjectMapContent {
1774    Simple(ObjectMapSimpleContent),
1775    Hub(ObjectMapHubContent),
1776}
1777
1778impl ObjectMapContent {
1779    pub fn mode(&self) -> ObjectMapContentMode {
1780        match self {
1781            Self::Simple(_) => ObjectMapContentMode::Simple,
1782            Self::Hub(_) => ObjectMapContentMode::Hub,
1783        }
1784    }
1785
1786    pub fn new_simple(content_type: ObjectMapSimpleContentType, depth: u8) -> Self {
1787        ObjectMapContent::Simple(ObjectMapSimpleContent::new(content_type, depth))
1788    }
1789
1790    pub fn new_hub(depth: u8) -> Self {
1791        ObjectMapContent::Hub(ObjectMapHubContent::new(depth))
1792    }
1793
1794    pub fn is_dirty(&self) -> bool {
1795        match self {
1796            Self::Simple(content) => content.is_dirty(),
1797            Self::Hub(content) => content.is_dirty(),
1798        }
1799    }
1800
1801    pub fn clear_dirty(&mut self) {
1802        match self {
1803            Self::Simple(content) => content.clear_dirty(),
1804            Self::Hub(content) => content.clear_dirty(),
1805        }
1806    }
1807
1808    /*
1809    // 刷新id
1810    pub fn flush_id(&mut self, cache: &ObjectMapOpEnvCacheRef) -> BuckyResult<()> {
1811        match self {
1812            Self::Simple(_) => Ok(()),
1813            Self::Hub(content) => content.flush_id(cache),
1814        }
1815    }
1816    */
1817
1818    // 模式转换 methods
1819    pub fn into_simple(self) -> ObjectMapSimpleContent {
1820        match self {
1821            Self::Simple(content) => content,
1822            Self::Hub(_) => unreachable!(),
1823        }
1824    }
1825
1826    pub async fn convert_to_hub(
1827        self,
1828        builder: &ObjectMapBuilder,
1829        cache: &ObjectMapOpEnvCacheRef,
1830    ) -> BuckyResult<Self> {
1831        match self {
1832            Self::Simple(content) => {
1833                let mut hub = ObjectMapHubContent::new(content.depth);
1834                match content.content {
1835                    SimpleContent::Map(values) => {
1836                        for (key, value) in values.into_values().into_iter() {
1837                            hub.insert_with_key(builder, cache, &key, &value).await?;
1838                        }
1839                    }
1840                    SimpleContent::DiffMap(values) => {
1841                        for (key, value) in values.into_values().into_iter() {
1842                            hub.diff_insert_with_key(builder, cache, &key, &value)
1843                                .await?;
1844                        }
1845                    }
1846                    SimpleContent::Set(values) => {
1847                        for value in values.into_values().into_iter() {
1848                            hub.insert(builder, cache, &value).await?;
1849                        }
1850                    }
1851                    SimpleContent::DiffSet(values) => {
1852                        for value in values.into_values().into_iter() {
1853                            hub.diff_insert(builder, cache, &value).await?;
1854                        }
1855                    }
1856                }
1857                let ret = Self::Hub(hub);
1858                Ok(ret)
1859            }
1860            Self::Hub(_) => Ok(self),
1861        }
1862    }
1863
1864    #[async_recursion::async_recursion]
1865    pub async fn convert_to_simple(
1866        self,
1867        cache: &ObjectMapOpEnvCacheRef,
1868        content_type: ObjectMapSimpleContentType,
1869    ) -> BuckyResult<Self> {
1870        match self {
1871            Self::Hub(content) => {
1872                let mut new_content = ObjectMapSimpleContent::new(content_type, content.depth);
1873
1874                // 对hub模式下的每个sub对象递归的进行转换操作
1875                for (_, sub) in content.subs.iter() {
1876                    let sub_obj = cache.get_object_map(&sub.id).await?;
1877                    if sub_obj.is_none() {
1878                        let msg = format!(
1879                            "convert object map to simple failed, sub obj not found! obj={}",
1880                            sub.id
1881                        );
1882                        error!("{}", msg);
1883                        return Err(BuckyError::new(BuckyErrorCode::NotFound, msg));
1884                    }
1885
1886                    let sub_obj = sub_obj.unwrap();
1887                    let simple_content;
1888                    {
1889                        let mut obj = sub_obj.lock().await.clone();
1890                        obj.convert_to_simple(cache).await?;
1891                        simple_content = obj.into_simple();
1892                    }
1893                    new_content.merge(simple_content)?;
1894                }
1895
1896                let ret = Self::Simple(new_content);
1897                Ok(ret)
1898            }
1899            Self::Simple(_) => Ok(self),
1900        }
1901    }
1902
1903    // visitor
1904    pub async fn visit(&self, visitor: &mut impl ObjectMapVisitor) -> BuckyResult<()> {
1905        match &self {
1906            Self::Simple(content) => content.visit(visitor).await,
1907            Self::Hub(content) => content.visit(visitor).await,
1908        }
1909    }
1910}
1911
1912// 用来缓存计算id
1913#[derive(Debug, Clone)]
1914struct ObjectMapContentHashCacheImpl {
1915    dirty: bool,
1916
1917    // 编码后的长度和内容
1918    // len: usize,
1919    // code_raw_buf: Option<Vec<u8>>,
1920
1921    // 缓存的对象id
1922    object_id: Option<ObjectId>,
1923}
1924
1925impl ObjectMapContentHashCacheImpl {
1926    pub fn new(object_id: ObjectId) -> Self {
1927        Self {
1928            dirty: false,
1929            object_id: Some(object_id),
1930        }
1931    }
1932
1933    pub fn new_empty() -> Self {
1934        Self {
1935            dirty: true,
1936            object_id: None,
1937        }
1938    }
1939
1940    // 设置cache的dirty状态
1941    fn mark_dirty(&mut self) -> bool {
1942        let ret = self.dirty;
1943        self.dirty = true;
1944        ret
1945    }
1946}
1947
1948struct ObjectMapContentHashCache(Mutex<ObjectMapContentHashCacheImpl>);
1949
1950impl Clone for ObjectMapContentHashCache {
1951    fn clone(&self) -> Self {
1952        let value = self.0.lock().unwrap().clone();
1953        Self(Mutex::new(value))
1954    }
1955}
1956
1957impl std::fmt::Debug for ObjectMapContentHashCache {
1958    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1959        let value = self.0.lock().unwrap();
1960        value.fmt(f)
1961    }
1962}
1963
1964impl ObjectMapContentHashCache {
1965    pub fn new(object_id: ObjectId) -> Self {
1966        Self(Mutex::new(ObjectMapContentHashCacheImpl::new(object_id)))
1967    }
1968
1969    pub fn new_empty() -> Self {
1970        Self(Mutex::new(ObjectMapContentHashCacheImpl::new_empty()))
1971    }
1972
1973    pub fn mark_dirty(&self) -> bool {
1974        self.0.lock().unwrap().mark_dirty()
1975    }
1976
1977    pub fn object_id(&self) -> Option<ObjectId> {
1978        self.0.lock().unwrap().object_id.clone()
1979    }
1980
1981    pub fn need_flush_id(&self) -> Option<ObjectId> {
1982        let cache = self.0.lock().unwrap();
1983        if !cache.dirty {
1984            assert!(cache.object_id.is_some());
1985            Some(cache.object_id.as_ref().unwrap().to_owned())
1986        } else {
1987            None
1988        }
1989    }
1990
1991    pub fn update_id(&self, object_id: &ObjectId) {
1992        let mut cache = self.0.lock().unwrap();
1993        cache.object_id = Some(object_id.clone());
1994        cache.dirty = false;
1995    }
1996
1997    pub fn direct_set_id_on_init(&self, object_id: ObjectId) {
1998        let mut cache = self.0.lock().unwrap();
1999        assert!(cache.dirty);
2000        assert!(cache.object_id.is_none());
2001
2002        cache.object_id = Some(object_id);
2003        cache.dirty = false;
2004    }
2005}
2006
2007// ObjectMap对象的分类
2008#[repr(u8)]
2009#[derive(Debug, Clone, Copy, Eq, PartialEq)]
2010pub enum ObjectMapClass {
2011    // 根节点
2012    Root = 0,
2013
2014    // hub模式下的子节点
2015    Sub = 1,
2016
2017    // DecRoot
2018    DecRoot = 2,
2019
2020    // GlobalRoot
2021    GlobalRoot = 3,
2022}
2023
2024impl ObjectMapClass {
2025    pub fn as_str(&self) -> &str {
2026        match self {
2027            Self::Root => "root",
2028            Self::Sub => "sub",
2029            Self::DecRoot => "dec-root",
2030            Self::GlobalRoot => "global-root",
2031        }
2032    }
2033}
2034
2035impl Into<u8> for ObjectMapClass {
2036    fn into(self) -> u8 {
2037        unsafe { std::mem::transmute(self as u8) }
2038    }
2039}
2040
2041use std::convert::TryFrom;
2042
2043impl TryFrom<u8> for ObjectMapClass {
2044    type Error = BuckyError;
2045    fn try_from(value: u8) -> Result<Self, Self::Error> {
2046        let ret = match value {
2047            0 => Self::Root,
2048            1 => Self::Sub,
2049            2 => Self::DecRoot,
2050            3 => Self::GlobalRoot,
2051
2052            _ => {
2053                let msg = format!("unknown objectmap class: {}", value);
2054                error!("{}", msg);
2055                return Err(BuckyError::new(BuckyErrorCode::InvalidData, msg));
2056            }
2057        };
2058
2059        Ok(ret)
2060    }
2061}
2062
2063pub struct ObjectMapMetaData {
2064    pub content_mode: ObjectMapContentMode,
2065    pub content_type: ObjectMapSimpleContentType,
2066    pub count: u64,
2067    pub size: u64,
2068    pub depth: u8,
2069}
2070
2071fn raw_encode_size(t: &(impl RawEncode + ?Sized)) -> u64 {
2072    t.raw_measure(&None).unwrap() as u64
2073}
2074
2075// 核心对象层的实现
2076#[derive(Clone, Debug)]
2077pub struct ObjectMapDescContent {
2078    // 对象类别
2079    class: ObjectMapClass,
2080
2081    // 子对象个数
2082    total: u64,
2083
2084    // 内容总大小
2085    size: u64,
2086
2087    // 当前深度,对于根对象,默认是0;对于sub objectmap,那么>0
2088    depth: u8,
2089
2090    content_type: ObjectMapSimpleContentType,
2091    content: ObjectMapContent,
2092
2093    hash_cache: ObjectMapContentHashCache,
2094}
2095
2096impl ObjectMapDescContent {
2097    pub fn new(class: ObjectMapClass, content_type: ObjectMapSimpleContentType, depth: u8) -> Self {
2098        Self {
2099            class,
2100            total: 0,
2101            size: 0,
2102            depth,
2103            content_type: content_type.clone(),
2104            content: ObjectMapContent::new_simple(content_type, depth),
2105            hash_cache: ObjectMapContentHashCache::new_empty(),
2106        }
2107    }
2108
2109    fn mark_dirty(&mut self) -> bool {
2110        // 首先重置content的dirty状态
2111        self.content.clear_dirty();
2112
2113        // 设置cache的dirty状态
2114        self.hash_cache.mark_dirty()
2115    }
2116
2117    pub fn count(&self) -> u64 {
2118        self.total
2119    }
2120
2121    pub fn size(&self) -> u64 {
2122        self.size
2123    }
2124
2125    pub fn depth(&self) -> u8 {
2126        self.depth
2127    }
2128
2129    pub fn object_id(&self) -> Option<ObjectId> {
2130        self.hash_cache.object_id()
2131    }
2132
2133    pub fn content_type(&self) -> &ObjectMapSimpleContentType {
2134        &self.content_type
2135    }
2136
2137    pub fn mode(&self) -> ObjectMapContentMode {
2138        self.content.mode()
2139    }
2140
2141    pub fn class(&self) -> ObjectMapClass {
2142        self.class.clone()
2143    }
2144
2145    pub fn set_class(&mut self, class: ObjectMapClass) {
2146        if self.class != class {
2147            self.class = class;
2148            self.mark_dirty();
2149        }
2150    }
2151
2152    pub fn content(&self) -> &ObjectMapContent {
2153        &self.content
2154
2155    }
2156    pub fn metadata(&self) -> ObjectMapMetaData {
2157        ObjectMapMetaData {
2158            content_type: self.content_type.clone(),
2159            content_mode: self.content.mode(),
2160            count: self.total,
2161            size: self.size,
2162            depth: self.depth,
2163        }
2164    }
2165
2166    // 模式转换
2167    pub fn into_simple(self) -> ObjectMapSimpleContent {
2168        self.content.into_simple()
2169    }
2170
2171    pub async fn convert_to_simple(&mut self, cache: &ObjectMapOpEnvCacheRef) -> BuckyResult<()> {
2172        let mut content = ObjectMapContent::new_simple(self.content_type.clone(), self.depth);
2173        std::mem::swap(&mut self.content, &mut content);
2174
2175        self.content = content
2176            .convert_to_simple(cache, self.content_type().clone())
2177            .await?;
2178
2179        self.mark_dirty();
2180
2181        Ok(())
2182    }
2183
2184    pub async fn convert_to_hub(
2185        &mut self,
2186        builder: &ObjectMapBuilder,
2187        cache: &ObjectMapOpEnvCacheRef,
2188    ) -> BuckyResult<()> {
2189        // debug!("objectmap begin convert to hub mode, id={:?}", self.object_id());
2190        let mut content = ObjectMapContent::new_hub(self.depth);
2191        std::mem::swap(&mut self.content, &mut content);
2192
2193        self.content = content.convert_to_hub(builder, cache).await?;
2194        self.mark_dirty();
2195
2196        // debug!("objectmap end convert to hub mode, id={:?}", self.object_id());
2197
2198        Ok(())
2199    }
2200
2201    // 增加操作的检查点
2202    pub async fn inflate_check_point(
2203        &mut self,
2204        builder: &ObjectMapBuilder,
2205        cache: &ObjectMapOpEnvCacheRef,
2206    ) -> BuckyResult<()> {
2207        match &self.content {
2208            ObjectMapContent::Simple(_) => {
2209                // 看编码大小是否超出64k限制
2210                if self.size > OBJECT_MAP_CONTENT_MAX_ENCODE_SIZE {
2211                    info!("object map simple content extend limit, now will convert to hub mode! id={:?}, size={}, count={}", 
2212                        self.object_id(), self.size, self.total);
2213                    self.convert_to_hub(builder, cache).await?;
2214                }
2215            }
2216            ObjectMapContent::Hub(_) => {
2217                assert!(self.size > OBJECT_MAP_CONTENT_MAX_ENCODE_SIZE);
2218            }
2219        }
2220
2221        Ok(())
2222    }
2223
2224    // 减少操作的检查点
2225    pub async fn deflate_check_point(&mut self, cache: &ObjectMapOpEnvCacheRef) -> BuckyResult<()> {
2226        match &self.content {
2227            ObjectMapContent::Simple(_) => {
2228                assert!(self.size <= OBJECT_MAP_CONTENT_MAX_ENCODE_SIZE);
2229            }
2230            ObjectMapContent::Hub(_) => {
2231                if self.size <= OBJECT_MAP_CONTENT_MAX_ENCODE_SIZE {
2232                    // 转换为simple模式
2233                    info!("object map hub content in limit, now will convert back to simple mode! count={}", self.total);
2234                    self.convert_to_simple(cache).await?;
2235                }
2236            }
2237        }
2238
2239        Ok(())
2240    }
2241
2242    // path methods
2243    pub async fn get_or_create_child_object_map(
2244        &mut self,
2245        builder: &ObjectMapBuilder,
2246        cache: &ObjectMapOpEnvCacheRef,
2247        key: &str,
2248        auto_create: ObjectMapCreateStrategy,
2249        access: Option<AccessString>,
2250    ) -> BuckyResult<Option<ObjectMapRef>> {
2251        assert!(!self.content.is_dirty());
2252
2253        let ret = match &mut self.content {
2254            ObjectMapContent::Simple(content) => {
2255                content
2256                    .get_or_create_child_object_map(builder, cache, key, auto_create, access)
2257                    .await
2258            }
2259            ObjectMapContent::Hub(content) => {
2260                content
2261                    .get_or_create_child_object_map(builder, cache, key, auto_create, access)
2262                    .await
2263            }
2264        }?;
2265
2266        // 内容发生改变,那么说明创建了新对象
2267        if self.content.is_dirty() {
2268            self.size += raw_encode_size(key) + ObjectId::raw_bytes().unwrap() as u64;
2269            self.total += 1;
2270            self.inflate_check_point(builder, cache).await?;
2271            self.mark_dirty();
2272        }
2273
2274        Ok(ret)
2275    }
2276
2277    // 展开内容到列表
2278    pub async fn list(
2279        &self,
2280        cache: &ObjectMapOpEnvCacheRef,
2281        list: &mut ObjectMapContentList,
2282    ) -> BuckyResult<u64> {
2283        match &self.content {
2284            ObjectMapContent::Simple(content) => content.list(list).map(|v| v as u64),
2285            ObjectMapContent::Hub(content) => content.list(cache, list).await,
2286        }
2287    }
2288
2289    pub async fn list_subs(
2290        &self,
2291        cache: &ObjectMapOpEnvCacheRef,
2292        list: &mut Vec<ObjectId>,
2293    ) -> BuckyResult<u64> {
2294        match &self.content {
2295            ObjectMapContent::Simple(_content) => Ok(0),
2296            ObjectMapContent::Hub(content) => content.list_subs(cache, list).await,
2297        }
2298    }
2299
2300    // 使用迭代器枚举
2301    pub async fn next(&self, it: &mut ObjectMapIterator) -> BuckyResult<()> {
2302        match &self.content {
2303            ObjectMapContent::Simple(content) => content.next(it),
2304            ObjectMapContent::Hub(content) => content.next(it).await,
2305        }
2306    }
2307
2308    pub(crate) fn diff(&self, other: &Self, diff: &mut ObjectMapDiff) {
2309        match &self.content {
2310            ObjectMapContent::Simple(content) => match &other.content {
2311                ObjectMapContent::Simple(other) => {
2312                    // 格式相同,直接计算diff
2313                    content.diff(other, diff);
2314                }
2315                ObjectMapContent::Hub(_) => {
2316                    unreachable!();
2317                }
2318            },
2319            ObjectMapContent::Hub(content) => match &other.content {
2320                ObjectMapContent::Simple(_) => {
2321                    unreachable!();
2322                }
2323                ObjectMapContent::Hub(other) => {
2324                    // 都是hub模式,那么递归的计算一次diff
2325                    content.diff(other, diff);
2326                }
2327            },
2328        }
2329    }
2330
2331    // map模式的相关接口
2332    pub async fn get_by_key(
2333        &self,
2334        cache: &ObjectMapOpEnvCacheRef,
2335        key: &str,
2336    ) -> BuckyResult<Option<ObjectId>> {
2337        match &self.content {
2338            ObjectMapContent::Simple(content) => content.get_by_key(key),
2339            ObjectMapContent::Hub(content) => content.get_by_key(cache, key).await,
2340        }
2341    }
2342
2343    pub async fn insert_with_key(
2344        &mut self,
2345        builder: &ObjectMapBuilder,
2346        cache: &ObjectMapOpEnvCacheRef,
2347        key: &str,
2348        value: &ObjectId,
2349    ) -> BuckyResult<()> {
2350        match &mut self.content {
2351            ObjectMapContent::Simple(content) => content.insert_with_key(key, value),
2352            ObjectMapContent::Hub(content) => {
2353                content.insert_with_key(builder, cache, key, value).await
2354            }
2355        }?;
2356
2357        self.size += raw_encode_size(key) + raw_encode_size(value);
2358        self.total += 1;
2359        self.inflate_check_point(builder, cache).await?;
2360        self.mark_dirty();
2361
2362        debug!(
2363            "objectmap insert_with_key, total={}, {}={}",
2364            self.total, key, value
2365        );
2366
2367        Ok(())
2368    }
2369
2370    pub async fn set_with_key(
2371        &mut self,
2372        builder: &ObjectMapBuilder,
2373        cache: &ObjectMapOpEnvCacheRef,
2374        key: &str,
2375        value: &ObjectId,
2376        prev_value: &Option<ObjectId>,
2377        auto_insert: bool,
2378    ) -> BuckyResult<Option<ObjectId>> {
2379        let ret = match &mut self.content {
2380            ObjectMapContent::Simple(content) => {
2381                content.set_with_key(key, value, prev_value, auto_insert)
2382            }
2383            ObjectMapContent::Hub(content) => {
2384                content
2385                    .set_with_key(builder, cache, key, value, prev_value, auto_insert)
2386                    .await
2387            }
2388        }?;
2389
2390        debug!(
2391            "objectmap set_with_key: key={}, value={}, prev={:?}, auto_insert={}, ret={:?}",
2392            key, value, prev_value, auto_insert, ret
2393        );
2394
2395        if ret.is_none() {
2396            // 插入了一个新元素
2397            self.size += raw_encode_size(key) + raw_encode_size(value);
2398            self.total += 1;
2399            self.inflate_check_point(builder, cache).await?;
2400            self.mark_dirty();
2401        } else {
2402            // 只是发生了replace操作,元素个数和大小不变
2403            if self.content.is_dirty() {
2404                self.mark_dirty();
2405            }
2406        }
2407
2408        Ok(ret)
2409    }
2410
2411    pub async fn remove_with_key(
2412        &mut self,
2413        cache: &ObjectMapOpEnvCacheRef,
2414        key: &str,
2415        prev_value: &Option<ObjectId>,
2416    ) -> BuckyResult<Option<ObjectId>> {
2417        let ret = match &mut self.content {
2418            ObjectMapContent::Simple(content) => content.remove_with_key(key, prev_value),
2419            ObjectMapContent::Hub(content) => content.remove_with_key(cache, key, prev_value).await,
2420        }?;
2421
2422        if ret.is_some() {
2423            assert!(self.total > 0);
2424            self.total -= 1;
2425
2426            let size = raw_encode_size(key) + raw_encode_size(ret.as_ref().unwrap());
2427            assert!(size <= self.size);
2428            self.size -= size;
2429
2430            self.deflate_check_point(cache).await?;
2431            self.mark_dirty();
2432        }
2433
2434        debug!(
2435            "objectmap remove_with_key, key={}, prev={:?}, ret={:?}",
2436            key, prev_value, ret
2437        );
2438
2439        Ok(ret)
2440    }
2441
2442    // diff map模式的相关接口
2443    pub async fn diff_get_by_key(
2444        &self,
2445        cache: &ObjectMapOpEnvCacheRef,
2446        key: &str,
2447    ) -> BuckyResult<Option<ObjectMapDiffMapItem>> {
2448        match &self.content {
2449            ObjectMapContent::Simple(content) => content.diff_get_by_key(key),
2450            ObjectMapContent::Hub(content) => content.diff_get_by_key(cache, key).await,
2451        }
2452    }
2453
2454    pub async fn diff_insert_with_key(
2455        &mut self,
2456        builder: &ObjectMapBuilder,
2457        cache: &ObjectMapOpEnvCacheRef,
2458        key: &str,
2459        value: &ObjectMapDiffMapItem,
2460    ) -> BuckyResult<()> {
2461        match &mut self.content {
2462            ObjectMapContent::Simple(content) => content.diff_insert_with_key(key, value),
2463            ObjectMapContent::Hub(content) => {
2464                content
2465                    .diff_insert_with_key(builder, cache, key, value)
2466                    .await
2467            }
2468        }?;
2469
2470        self.size += raw_encode_size(key) + raw_encode_size(value);
2471        self.total += 1;
2472        self.inflate_check_point(builder, cache).await?;
2473        self.mark_dirty();
2474
2475        debug!(
2476            "objectmap diff_insert_with_key, total={}, {}={}",
2477            self.total, key, value
2478        );
2479
2480        Ok(())
2481    }
2482
2483    pub async fn diff_set_with_key(
2484        &mut self,
2485        builder: &ObjectMapBuilder,
2486        cache: &ObjectMapOpEnvCacheRef,
2487        key: &str,
2488        value: &ObjectMapDiffMapItem,
2489        prev_value: &Option<ObjectMapDiffMapItem>,
2490        auto_insert: bool,
2491    ) -> BuckyResult<Option<ObjectMapDiffMapItem>> {
2492        let ret = match &mut self.content {
2493            ObjectMapContent::Simple(content) => {
2494                content.diff_set_with_key(key, value, &prev_value, auto_insert)
2495            }
2496            ObjectMapContent::Hub(content) => {
2497                content
2498                    .diff_set_with_key(builder, cache, key, value, prev_value, auto_insert)
2499                    .await
2500            }
2501        }?;
2502
2503        debug!(
2504            "objectmap diff_set_with_key: key={}, value={}, prev={:?}, auto_insert={}, ret={:?}",
2505            key, value, prev_value, auto_insert, ret
2506        );
2507
2508        if ret.is_none() {
2509            // 插入了一个新元素
2510            self.size += raw_encode_size(key) + raw_encode_size(value);
2511            self.total += 1;
2512            self.inflate_check_point(builder, cache).await?;
2513            self.mark_dirty();
2514        } else {
2515            // 只是发生了replace操作,元素个数不变,大小可能改变
2516            let current = self.size;
2517            self.size += raw_encode_size(value);
2518            self.size -= raw_encode_size(ret.as_ref().unwrap());
2519
2520            if self.size > current {
2521                self.inflate_check_point(builder, cache).await?;
2522            } else if self.size < current {
2523                self.deflate_check_point(cache).await?;
2524            }
2525
2526            if self.content.is_dirty() {
2527                self.mark_dirty();
2528            }
2529        }
2530
2531        Ok(ret)
2532    }
2533
2534    pub async fn diff_remove_with_key(
2535        &mut self,
2536        cache: &ObjectMapOpEnvCacheRef,
2537        key: &str,
2538        prev_value: &Option<ObjectMapDiffMapItem>,
2539    ) -> BuckyResult<Option<ObjectMapDiffMapItem>> {
2540        let ret = match &mut self.content {
2541            ObjectMapContent::Simple(content) => content.diff_remove_with_key(key, &prev_value),
2542            ObjectMapContent::Hub(content) => {
2543                content.diff_remove_with_key(cache, key, prev_value).await
2544            }
2545        }?;
2546
2547        debug!(
2548            "objectmap diff_remove_with_key, key={}, prev={:?}, ret={:?}",
2549            key, prev_value, ret
2550        );
2551
2552        if ret.is_some() {
2553            assert!(self.total > 0);
2554            self.total -= 1;
2555
2556            let size = raw_encode_size(key) + raw_encode_size(ret.as_ref().unwrap());
2557            assert!(size <= self.size);
2558            self.size -= size;
2559
2560            self.deflate_check_point(cache).await?;
2561            self.mark_dirty();
2562        }
2563
2564        Ok(ret)
2565    }
2566
2567    // set模式的相关接口
2568    pub async fn contains(
2569        &self,
2570        cache: &ObjectMapOpEnvCacheRef,
2571        object_id: &ObjectId,
2572    ) -> BuckyResult<bool> {
2573        match &self.content {
2574            ObjectMapContent::Simple(content) => content.contains(object_id),
2575            ObjectMapContent::Hub(content) => content.contains(cache, object_id).await,
2576        }
2577    }
2578
2579    pub async fn insert(
2580        &mut self,
2581        builder: &ObjectMapBuilder,
2582        cache: &ObjectMapOpEnvCacheRef,
2583        object_id: &ObjectId,
2584    ) -> BuckyResult<bool> {
2585        let ret = match &mut self.content {
2586            ObjectMapContent::Simple(content) => content.insert(object_id),
2587            ObjectMapContent::Hub(content) => content.insert(builder, cache, object_id).await,
2588        }?;
2589
2590        if ret {
2591            self.total += 1;
2592            self.size += raw_encode_size(object_id);
2593            self.inflate_check_point(builder, cache).await?;
2594            self.mark_dirty();
2595        }
2596
2597        debug!(
2598            "objectmap insert, value={}, count={}, ret={}",
2599            object_id, self.total, ret
2600        );
2601
2602        Ok(ret)
2603    }
2604
2605    pub async fn remove(
2606        &mut self,
2607        cache: &ObjectMapOpEnvCacheRef,
2608        object_id: &ObjectId,
2609    ) -> BuckyResult<bool> {
2610        let ret = match &mut self.content {
2611            ObjectMapContent::Simple(content) => content.remove(object_id),
2612            ObjectMapContent::Hub(content) => content.remove(cache, object_id).await,
2613        }?;
2614
2615        if ret {
2616            assert!(self.total > 0);
2617            self.total -= 1;
2618            let size = raw_encode_size(object_id);
2619            assert!(size <= self.size);
2620            self.size -= size;
2621
2622            self.deflate_check_point(cache).await?;
2623            self.mark_dirty();
2624        }
2625
2626        debug!(
2627            "objectmap remove, value={}, count={}, ret={}",
2628            object_id, self.total, ret
2629        );
2630
2631        Ok(ret)
2632    }
2633
2634    // diff set模式的相关接口
2635    pub async fn diff_contains(
2636        &self,
2637        cache: &ObjectMapOpEnvCacheRef,
2638        object_id: &ObjectMapDiffSetItem,
2639    ) -> BuckyResult<bool> {
2640        match &self.content {
2641            ObjectMapContent::Simple(content) => content.diff_contains(object_id),
2642            ObjectMapContent::Hub(content) => content.diff_contains(cache, object_id).await,
2643        }
2644    }
2645
2646    pub async fn diff_insert(
2647        &mut self,
2648        builder: &ObjectMapBuilder,
2649        cache: &ObjectMapOpEnvCacheRef,
2650        object_id: &ObjectMapDiffSetItem,
2651    ) -> BuckyResult<bool> {
2652        let ret = match &mut self.content {
2653            ObjectMapContent::Simple(content) => content.diff_insert(object_id),
2654            ObjectMapContent::Hub(content) => content.diff_insert(builder, cache, object_id).await,
2655        }?;
2656
2657        if ret {
2658            self.total += 1;
2659            self.size += raw_encode_size(object_id);
2660            self.inflate_check_point(builder, cache).await?;
2661            self.mark_dirty();
2662        }
2663
2664        debug!(
2665            "objectmap diff_insert, value={}, count={}, ret={}",
2666            object_id, self.total, ret
2667        );
2668
2669        Ok(ret)
2670    }
2671
2672    pub async fn diff_remove(
2673        &mut self,
2674        cache: &ObjectMapOpEnvCacheRef,
2675        object_id: &ObjectMapDiffSetItem,
2676    ) -> BuckyResult<bool> {
2677        let ret = match &mut self.content {
2678            ObjectMapContent::Simple(content) => content.diff_remove(object_id),
2679            ObjectMapContent::Hub(content) => content.diff_remove(cache, object_id).await,
2680        }?;
2681
2682        if ret {
2683            assert!(self.total > 0);
2684            self.total -= 1;
2685            let size = raw_encode_size(object_id);
2686            assert!(size >= self.size);
2687            self.size -= size;
2688
2689            self.deflate_check_point(cache).await?;
2690            self.mark_dirty();
2691        }
2692
2693        debug!(
2694            "objectmap diff_remove, value={}, count={}, ret={}",
2695            object_id, self.total, ret
2696        );
2697
2698        Ok(ret)
2699    }
2700
2701    // visitor
2702    pub async fn visit(&self, visitor: &mut impl ObjectMapVisitor) -> BuckyResult<()> {
2703        match &self.content {
2704            ObjectMapContent::Simple(content) => content.visit(visitor).await,
2705            ObjectMapContent::Hub(content) => content.visit(visitor).await,
2706        }
2707    }
2708}
2709
2710impl RawEncode for ObjectMapDescContent {
2711    fn raw_measure(&self, purpose: &Option<RawEncodePurpose>) -> BuckyResult<usize> {
2712        let ret = u8::raw_bytes().unwrap() // class
2713            + self.total.raw_measure(purpose)?
2714            + self.size.raw_measure(purpose)?
2715            + self.depth.raw_measure(purpose)?
2716            + self.content_type.raw_measure(purpose)?
2717            + self.content.raw_measure(purpose)?;
2718
2719        // for debug
2720        // debug!("objectmap raw_measure {:?} size={}", self, ret);
2721
2722        Ok(ret)
2723    }
2724
2725    fn raw_encode<'a>(
2726        &self,
2727        buf: &'a mut [u8],
2728        purpose: &Option<RawEncodePurpose>,
2729    ) -> BuckyResult<&'a mut [u8]> {
2730        let class: u8 = self.class.clone().into();
2731        let buf = class.raw_encode(buf, purpose)?;
2732
2733        let buf = self.total.raw_encode(buf, purpose)?;
2734        let buf = self.size.raw_encode(buf, purpose)?;
2735        let buf = self.depth.raw_encode(buf, purpose)?;
2736        let buf = self.content_type.raw_encode(buf, purpose)?;
2737        let buf = self.content.raw_encode(buf, purpose)?;
2738
2739        Ok(buf)
2740    }
2741}
2742
2743impl RawDecode<'_> for ObjectMapDescContent {
2744    fn raw_decode(buf: &[u8]) -> BuckyResult<(Self, &[u8])> {
2745        let (class, buf) = u8::raw_decode(buf).map_err(|e| {
2746            error!("ObjectMapDescContent::raw_decode/class error:{}", e);
2747            e
2748        })?;
2749
2750        let class = ObjectMapClass::try_from(class)?;
2751
2752        let (total, buf) = u64::raw_decode(buf).map_err(|e| {
2753            error!("ObjectMapDescContent::raw_decode/total error:{}", e);
2754            e
2755        })?;
2756
2757        let (size, buf) = u64::raw_decode(buf).map_err(|e| {
2758            error!("ObjectMapDescContent::raw_decode/size error:{}", e);
2759            e
2760        })?;
2761
2762        let (depth, buf) = u8::raw_decode(buf).map_err(|e| {
2763            error!("ObjectMapDescContent::raw_decode/depth error:{}", e);
2764            e
2765        })?;
2766
2767        let (content_type, buf) = ObjectMapSimpleContentType::raw_decode(buf).map_err(|e| {
2768            error!("ObjectMapDescContent::raw_decode/content_type error:{}", e);
2769            e
2770        })?;
2771
2772        let (content, buf) = ObjectMapContent::raw_decode(buf).map_err(|e| {
2773            error!("ObjectMapDescContent::raw_decode/content error:{}", e);
2774            e
2775        })?;
2776
2777        // 如果解码后剩余buf不为零,那么hash_value需要重新计算
2778        let ret = Self {
2779            class,
2780            total,
2781            size,
2782            depth,
2783            content_type,
2784            content,
2785
2786            hash_cache: ObjectMapContentHashCache::new_empty(),
2787        };
2788
2789        Ok((ret, buf))
2790    }
2791}
2792
2793impl DescContent for ObjectMapDescContent {
2794    fn obj_type() -> u16 {
2795        ObjectTypeCode::ObjectMap.into()
2796    }
2797
2798    type OwnerType = Option<ObjectId>;
2799    type AreaType = SubDescNone;
2800    type AuthorType = SubDescNone;
2801    type PublicKeyType = SubDescNone;
2802}
2803
2804#[derive(Clone, Debug, RawEncode, RawDecode)]
2805pub struct ObjectMapBodyContent;
2806
2807impl BodyContent for ObjectMapBodyContent {}
2808
2809pub type ObjectMapType = NamedObjType<ObjectMapDescContent, ObjectMapBodyContent>;
2810pub type ObjectMapBuilder = NamedObjectBuilder<ObjectMapDescContent, ObjectMapBodyContent>;
2811
2812pub type ObjectMapDesc = NamedObjectDesc<ObjectMapDescContent>;
2813pub type ObjectMapId = NamedObjectId<ObjectMapType>;
2814pub type ObjectMap = NamedObjectBase<ObjectMapType>;
2815
2816impl ObjectMapBuilder {
2817    pub fn content_type(&self) -> ObjectMapSimpleContentType {
2818        self.desc_builder().desc_content().content_type.clone()
2819    }
2820
2821    pub fn class(mut self, class: ObjectMapClass) -> Self {
2822        self.mut_desc_builder().mut_desc_content().class = class;
2823        self
2824    }
2825}
2826
2827impl ObjectMap {
2828    pub fn new(
2829        content_type: ObjectMapSimpleContentType,
2830        owner: Option<ObjectId>,
2831        dec_id: Option<ObjectId>,
2832    ) -> ObjectMapBuilder {
2833        let desc_content = ObjectMapDescContent::new(ObjectMapClass::Root, content_type, 0);
2834        let body_content = ObjectMapBodyContent {};
2835
2836        ObjectMapBuilder::new(desc_content, body_content)
2837            .option_owner(owner)
2838            .option_dec_id(dec_id)
2839            .no_create_time()
2840    }
2841
2842    fn new_sub_builder(
2843        &self,
2844        content_type: Option<ObjectMapSimpleContentType>,
2845    ) -> BuckyResult<ObjectMapBuilder> {
2846        let content_type = match content_type {
2847            Some(content_type) => content_type,
2848            None => self.desc().content().content_type().to_owned(),
2849        };
2850
2851        // 均衡hash情况下,基本不可能到达这个深度,但我们还是增加一个检测
2852        let depth = self.depth();
2853        if depth == u8::MAX {
2854            let msg = format!("object map depth extend max limit! max={}", u8::MAX);
2855            error!("{}", msg);
2856            return Err(BuckyError::new(BuckyErrorCode::OutOfLimit, msg));
2857        }
2858
2859        let desc_content = ObjectMapDescContent::new(ObjectMapClass::Sub, content_type, depth + 1);
2860        let body_content = ObjectMapBodyContent {};
2861
2862        let builder = ObjectMapBuilder::new(desc_content, body_content)
2863            .option_owner(self.desc().owner().to_owned())
2864            .option_dec_id(self.desc().dec_id().to_owned())
2865            .no_create_time();
2866
2867        Ok(builder)
2868    }
2869
2870    pub fn count(&self) -> u64 {
2871        self.desc().content().count()
2872    }
2873
2874    pub fn object_id(&self) -> ObjectId {
2875        self.flush_id()
2876    }
2877
2878    pub fn content_type(&self) -> ObjectMapSimpleContentType {
2879        self.desc().content().content_type().to_owned()
2880    }
2881
2882    pub fn mode(&self) -> ObjectMapContentMode {
2883        self.desc().content().mode()
2884    }
2885
2886    pub fn class(&self) -> ObjectMapClass {
2887        self.desc().content().class()
2888    }
2889
2890    pub fn depth(&self) -> u8 {
2891        self.desc().content().depth
2892    }
2893
2894    pub fn metadata(&self) -> ObjectMapMetaData {
2895        self.desc().content().metadata()
2896    }
2897    // 获取缓存的object_id
2898    pub fn cached_object_id(&self) -> Option<ObjectId> {
2899        self.desc().content().hash_cache.object_id()
2900    }
2901
2902    // decode后,直接设置id
2903    pub fn direct_set_object_id_on_init(&self, object_id: &ObjectId) {
2904        #[cfg(debug_assertions)]
2905        {
2906            let real_id = self.flush_id_without_cache();
2907            assert_eq!(real_id, *object_id);
2908        }
2909
2910        self.desc()
2911            .content()
2912            .hash_cache
2913            .direct_set_id_on_init(object_id.to_owned());
2914    }
2915
2916    // 刷新并计算id
2917    pub fn flush_id(&self) -> ObjectId {
2918        // 首先判断是否需要重新计算id
2919        if let Some(object_id) = self.desc().content().hash_cache.need_flush_id() {
2920            return object_id;
2921        }
2922
2923        // 发起一次重新计算
2924        let id = self.desc().calculate_id();
2925
2926        // 缓存最新的id
2927        self.desc().content().hash_cache.update_id(&id);
2928
2929        id
2930    }
2931
2932    // 强制发起一次重新计算,不会读取和更新缓存
2933    pub fn flush_id_without_cache(&self) -> ObjectId {
2934        self.desc().calculate_id()
2935    }
2936
2937    // 模式转换相关函数
2938    // hub->simple
2939    pub async fn convert_to_simple(&mut self, cache: &ObjectMapOpEnvCacheRef) -> BuckyResult<()> {
2940        self.desc_mut().content_mut().convert_to_simple(cache).await
2941    }
2942
2943    pub async fn convert_to_hub(&mut self, cache: &ObjectMapOpEnvCacheRef) -> BuckyResult<()> {
2944        let builder = self.new_sub_builder(None)?;
2945
2946        self.desc_mut()
2947            .content_mut()
2948            .convert_to_hub(&builder, cache)
2949            .await
2950    }
2951
2952    pub fn into_simple(self) -> ObjectMapSimpleContent {
2953        self.into_desc().into_content().into_simple()
2954    }
2955
2956    // 用以对基于path的多级objectmap的支持
2957    pub async fn get_or_create_child_object_map(
2958        &mut self,
2959        cache: &ObjectMapOpEnvCacheRef,
2960        key: &str,
2961        content_type: ObjectMapSimpleContentType,
2962        auto_create: ObjectMapCreateStrategy,
2963        access: Option<AccessString>,
2964    ) -> BuckyResult<Option<ObjectMapRef>> {
2965        let builder = self.new_sub_builder(Some(content_type))?;
2966        self.desc_mut()
2967            .content_mut()
2968            .get_or_create_child_object_map(&builder, cache, key, auto_create, access)
2969            .await
2970    }
2971
2972    // list all values/keypairs
2973    pub async fn list(
2974        &self,
2975        cache: &ObjectMapOpEnvCacheRef,
2976        list: &mut ObjectMapContentList,
2977    ) -> BuckyResult<u64> {
2978        self.desc().content().list(cache, list).await
2979    }
2980
2981    pub async fn list_direct(
2982        &self,
2983        cache: &ObjectMapOpEnvCacheRef,
2984    ) -> BuckyResult<ObjectMapContentList> {
2985        let mut list = ObjectMapContentList::new(self.count() as usize);
2986        self.desc().content().list(cache, &mut list).await?;
2987        Ok(list)
2988    }
2989
2990    // list all subs objects in sub mode
2991    pub async fn list_subs(
2992        &self,
2993        cache: &ObjectMapOpEnvCacheRef,
2994        list: &mut Vec<ObjectId>,
2995    ) -> BuckyResult<u64> {
2996        self.desc().content().list_subs(cache, list).await
2997    }
2998
2999    // 迭代器
3000    pub async fn next(&self, it: &mut ObjectMapIterator) -> BuckyResult<()> {
3001        self.desc().content().next(it).await
3002    }
3003
3004    // 计算直接的diff,不能同步计算的diff,放到pending列表
3005    pub(crate) fn diff(&self, other: &Self, diff: &mut ObjectMapDiff) {
3006        assert_eq!(self.content_type(), other.content_type());
3007
3008        match self.mode() {
3009            ObjectMapContentMode::Hub => match other.mode() {
3010                ObjectMapContentMode::Hub => {
3011                    self.desc().content().diff(other.desc().content(), diff);
3012                }
3013                ObjectMapContentMode::Simple => {
3014                    diff.pend_async_alter(
3015                        self.cached_object_id().unwrap(),
3016                        other.cached_object_id().unwrap(),
3017                    );
3018                }
3019            },
3020            ObjectMapContentMode::Simple => match other.mode() {
3021                ObjectMapContentMode::Hub => {
3022                    diff.pend_async_alter(
3023                        self.cached_object_id().unwrap(),
3024                        other.cached_object_id().unwrap(),
3025                    );
3026                }
3027                ObjectMapContentMode::Simple => {
3028                    self.desc().content().diff(other.desc().content(), diff);
3029                }
3030            },
3031        }
3032    }
3033
3034    // map类型相关接口
3035    pub async fn get_by_key(
3036        &self,
3037        cache: &ObjectMapOpEnvCacheRef,
3038        key: &str,
3039    ) -> BuckyResult<Option<ObjectId>> {
3040        self.desc().content().get_by_key(cache, key).await
3041    }
3042
3043    pub async fn insert_with_key(
3044        &mut self,
3045        cache: &ObjectMapOpEnvCacheRef,
3046        key: &str,
3047        value: &ObjectId,
3048    ) -> BuckyResult<()> {
3049        let builder = self.new_sub_builder(None)?;
3050        self.desc_mut()
3051            .content_mut()
3052            .insert_with_key(&builder, cache, key, value)
3053            .await
3054    }
3055
3056    pub async fn set_with_key(
3057        &mut self,
3058        cache: &ObjectMapOpEnvCacheRef,
3059        key: &str,
3060        value: &ObjectId,
3061        prev_value: &Option<ObjectId>,
3062        auto_insert: bool,
3063    ) -> BuckyResult<Option<ObjectId>> {
3064        let builder = self.new_sub_builder(None)?;
3065        self.desc_mut()
3066            .content_mut()
3067            .set_with_key(&builder, cache, key, value, prev_value, auto_insert)
3068            .await
3069    }
3070
3071    pub async fn remove_with_key(
3072        &mut self,
3073        cache: &ObjectMapOpEnvCacheRef,
3074        key: &str,
3075        prev_value: &Option<ObjectId>,
3076    ) -> BuckyResult<Option<ObjectId>> {
3077        self.desc_mut()
3078            .content_mut()
3079            .remove_with_key(cache, key, prev_value)
3080            .await
3081    }
3082
3083    // diffmap类型相关接口
3084    pub async fn diff_get_by_key(
3085        &self,
3086        cache: &ObjectMapOpEnvCacheRef,
3087        key: &str,
3088    ) -> BuckyResult<Option<ObjectMapDiffMapItem>> {
3089        self.desc().content().diff_get_by_key(cache, key).await
3090    }
3091
3092    pub async fn diff_insert_with_key(
3093        &mut self,
3094        cache: &ObjectMapOpEnvCacheRef,
3095        key: &str,
3096        value: &ObjectMapDiffMapItem,
3097    ) -> BuckyResult<()> {
3098        let builder = self.new_sub_builder(None)?;
3099        self.desc_mut()
3100            .content_mut()
3101            .diff_insert_with_key(&builder, cache, key, value)
3102            .await
3103    }
3104
3105    pub async fn diff_set_with_key(
3106        &mut self,
3107        cache: &ObjectMapOpEnvCacheRef,
3108        key: &str,
3109        value: &ObjectMapDiffMapItem,
3110        prev_value: &Option<ObjectMapDiffMapItem>,
3111        auto_insert: bool,
3112    ) -> BuckyResult<Option<ObjectMapDiffMapItem>> {
3113        let builder = self.new_sub_builder(None)?;
3114        self.desc_mut()
3115            .content_mut()
3116            .diff_set_with_key(&builder, cache, key, value, prev_value, auto_insert)
3117            .await
3118    }
3119
3120    pub async fn diff_remove_with_key(
3121        &mut self,
3122        cache: &ObjectMapOpEnvCacheRef,
3123        key: &str,
3124        prev_value: &Option<ObjectMapDiffMapItem>,
3125    ) -> BuckyResult<Option<ObjectMapDiffMapItem>> {
3126        self.desc_mut()
3127            .content_mut()
3128            .diff_remove_with_key(cache, key, prev_value)
3129            .await
3130    }
3131
3132    // set类型相关接口
3133    pub async fn contains(
3134        &self,
3135        cache: &ObjectMapOpEnvCacheRef,
3136        object_id: &ObjectId,
3137    ) -> BuckyResult<bool> {
3138        self.desc().content().contains(cache, object_id).await
3139    }
3140
3141    pub async fn insert(
3142        &mut self,
3143        cache: &ObjectMapOpEnvCacheRef,
3144        object_id: &ObjectId,
3145    ) -> BuckyResult<bool> {
3146        let builder = self.new_sub_builder(None)?;
3147        self.desc_mut()
3148            .content_mut()
3149            .insert(&builder, cache, object_id)
3150            .await
3151    }
3152
3153    pub async fn remove(
3154        &mut self,
3155        cache: &ObjectMapOpEnvCacheRef,
3156        object_id: &ObjectId,
3157    ) -> BuckyResult<bool> {
3158        self.desc_mut().content_mut().remove(cache, object_id).await
3159    }
3160
3161    // diffset类型相关接口
3162    pub async fn diff_contains(
3163        &self,
3164        cache: &ObjectMapOpEnvCacheRef,
3165        object_id: &ObjectMapDiffSetItem,
3166    ) -> BuckyResult<bool> {
3167        self.desc().content().diff_contains(cache, object_id).await
3168    }
3169
3170    pub async fn diff_insert(
3171        &mut self,
3172        cache: &ObjectMapOpEnvCacheRef,
3173        object_id: &ObjectMapDiffSetItem,
3174    ) -> BuckyResult<bool> {
3175        let builder = self.new_sub_builder(None)?;
3176        self.desc_mut()
3177            .content_mut()
3178            .diff_insert(&builder, cache, object_id)
3179            .await
3180    }
3181
3182    pub async fn diff_remove(
3183        &mut self,
3184        cache: &ObjectMapOpEnvCacheRef,
3185        object_id: &ObjectMapDiffSetItem,
3186    ) -> BuckyResult<bool> {
3187        self.desc_mut()
3188            .content_mut()
3189            .diff_remove(cache, object_id)
3190            .await
3191    }
3192
3193    pub async fn visit(&self, visitor: &mut impl ObjectMapVisitor) -> BuckyResult<()> {
3194        self.desc().content().visit(visitor).await
3195    }
3196}
3197
3198#[cfg(test)]
3199mod test_desc_limit {
3200    use super::*;
3201
3202    struct ObjectMapSlim {
3203        // 对象类别
3204        class: ObjectMapClass,
3205
3206        // 子对象个数
3207        total: u64,
3208
3209        // 内容总大小
3210        size: u64,
3211
3212        // 当前深度,对于根对象,默认是0;对于sub objectmap,那么>0
3213        depth: u8,
3214
3215        content_type: ObjectMapSimpleContentType,
3216    }
3217
3218    impl RawEncode for ObjectMapSlim {
3219        fn raw_measure(&self, purpose: &Option<RawEncodePurpose>) -> BuckyResult<usize> {
3220            let ret = u8::raw_bytes().unwrap() // class
3221            + self.total.raw_measure(purpose)?
3222            + self.size.raw_measure(purpose)?
3223            + self.depth.raw_measure(purpose)?
3224            + self.content_type.raw_measure(purpose)?;
3225
3226            // for debug
3227            // debug!("objectmap raw_measure {:?} size={}", self, ret);
3228
3229            Ok(ret)
3230        }
3231
3232        fn raw_encode<'a>(
3233            &self,
3234            _buf: &'a mut [u8],
3235            _purpose: &Option<RawEncodePurpose>,
3236        ) -> BuckyResult<&'a mut [u8]> {
3237            unimplemented!();
3238        }
3239    }
3240
3241    #[test]
3242    fn object_map_desc_max_size() {
3243        let slim = ObjectMapSlim {
3244            class: ObjectMapClass::Root,
3245            total: 1024,
3246            size: 1024,
3247            depth: 0,
3248            content_type: ObjectMapSimpleContentType::Map,
3249        };
3250
3251        let size = slim.raw_measure(&None).unwrap();
3252        println!("{}", size);
3253    }
3254}
3255
3256#[cfg(test)]
3257mod test {
3258    use super::super::cache::*;
3259    use super::*;
3260    use crate::*;
3261
3262    use rand::distributions::Alphanumeric;
3263    use rand::{thread_rng, Rng};
3264
3265    fn gen_random_key(len: usize) -> String {
3266        let rand_string: String = thread_rng()
3267            .sample_iter(&Alphanumeric)
3268            .take(len)
3269            .map(char::from)
3270            .collect();
3271
3272        println!("{}", rand_string);
3273        rand_string
3274    }
3275
3276    async fn test_map() {
3277        let noc = ObjectMapMemoryNOCCache::new();
3278        let root_cache = ObjectMapRootMemoryCache::new_default_ref(None, noc);
3279        let cache = ObjectMapOpEnvMemoryCache::new_ref(root_cache.clone());
3280
3281        let owner = ObjectId::default();
3282        let mut map = ObjectMap::new(
3283            ObjectMapSimpleContentType::Map,
3284            Some(owner.clone()),
3285            Some(owner.clone()),
3286        )
3287        .no_create_time()
3288        .build();
3289        for i in 0..10000 {
3290            let key = format!("test_map_{}", i);
3291            let object_id = ObjectId::default();
3292            map.insert_with_key(&cache, &key, &object_id).await.unwrap();
3293        }
3294
3295        let mut subs = vec![];
3296        map.list_subs(&cache, &mut subs).await.unwrap();
3297        info!("subs: {:?}", subs);
3298
3299        let object_id = ObjectId::default();
3300        for i in 0..10000 {
3301            let key = format!("test_map_{}", i);
3302            let ret = map.get_by_key(&cache, &key).await.unwrap();
3303            assert_eq!(ret, Some(object_id));
3304        }
3305
3306        /*
3307        for i in 0..10000 {
3308            let key = format!("test_map_{}", i);
3309            let ret = map.remove_with_key(&cache, &key, &None).await.unwrap();
3310            assert_eq!(ret, Some(object_id));
3311        }
3312        */
3313
3314        // assert_eq!(map.count(), 0);
3315
3316        let id = map.flush_id();
3317        info!("obj map id={}", id);
3318
3319        cache.put_object_map(&id, map, None).unwrap();
3320        cache.gc(true, &id).await.unwrap();
3321    }
3322
3323    async fn test_set() {
3324        let noc = ObjectMapMemoryNOCCache::new();
3325        let root_cache = ObjectMapRootMemoryCache::new_default_ref(None, noc);
3326        let cache = ObjectMapOpEnvMemoryCache::new_ref(root_cache.clone());
3327
3328        let owner = ObjectId::default();
3329        let mut map = ObjectMap::new(
3330            ObjectMapSimpleContentType::Set,
3331            Some(owner.clone()),
3332            Some(owner.clone()),
3333        )
3334        .no_create_time()
3335        .build();
3336
3337        fn object_id_from_index(index: i32) -> ObjectId {
3338            let key = format!("test_set_{}", index);
3339            let chunk_id = ChunkId::calculate_sync(key.as_bytes()).unwrap();
3340            let object_id = chunk_id.object_id();
3341            object_id
3342        }
3343
3344        for i in 0..10000 {
3345            let object_id = object_id_from_index(i);
3346            let ret = map.insert(&cache, &object_id).await.unwrap();
3347            assert!(ret);
3348
3349            let ret = map.insert(&cache, &object_id).await.unwrap();
3350            assert!(!ret);
3351        }
3352
3353        for i in 0..10000 {
3354            let object_id = object_id_from_index(i);
3355            let ret = map.contains(&cache, &object_id).await.unwrap();
3356            assert!(ret);
3357        }
3358
3359        for i in 0..10000 {
3360            let object_id = object_id_from_index(i);
3361            let ret = map.remove(&cache, &object_id).await.unwrap();
3362            assert!(ret);
3363        }
3364
3365        assert_eq!(map.count(), 0);
3366
3367        let id = map.flush_id();
3368        info!("obj map id={}", id);
3369    }
3370
3371    #[test]
3372    fn test() {
3373        crate::init_simple_log("test-object-map", Some("debug"));
3374        async_std::task::block_on(async move {
3375            // test_set().await;
3376            test_map().await;
3377        });
3378    }
3379
3380    #[test]
3381    fn test_path_string() {
3382        let path = "/a/b/c";
3383        let parts = path.split("/").skip(1);
3384        for part in parts {
3385            println!("part={}", part);
3386        }
3387    }
3388
3389    #[test]
3390    fn test_hub_fix_limit() {
3391        let mut content = ObjectMapHubContent {
3392            depth: 0,
3393            subs: BTreeMap::new(),
3394            dirty: false,
3395        };
3396
3397        let mut index = 0;
3398        let object_id = ObjectId::default();
3399        loop {
3400            let item = ObjectMapHubItem {
3401                id: object_id.clone(),
3402            };
3403            content.subs.insert(index, item);
3404            let len = content.raw_measure(&None).unwrap();
3405            if len > u16::MAX as usize {
3406                println!("touch desc limit! index ={}", index);
3407                break;
3408            }
3409            index += 1;
3410        }
3411    }
3412
3413    #[test]
3414    fn test_simple_map_limit() {
3415        use std::str::FromStr;
3416
3417        let object_id = ObjectId::default();
3418        let object_id = ObjectId::from_str("95RvaS5Wy2UZC4Pzy7A6PZTs47bsWLCPtZe834oVvbQ4").unwrap();
3419        let s = object_id.to_string();
3420        let len = object_id.raw_measure(&None).unwrap() + s.raw_measure(&None).unwrap();
3421        println!("len={}", len);
3422
3423        let mut content = ObjectMapSimpleContent::new(ObjectMapSimpleContentType::Map, 0);
3424        let object_id = ObjectId::default();
3425        let mut index = 0;
3426        loop {
3427            let key = gen_random_key(OBJECT_MAP_KEY_MAX_LEN);
3428            content.insert_with_key(&key, &object_id).unwrap();
3429            let len = content.raw_measure(&None).unwrap();
3430            if len > u16::MAX as usize {
3431                println!("touch simple map limit! index ={}", index);
3432                break;
3433            }
3434
3435            index += 1;
3436        }
3437    }
3438
3439    #[test]
3440    fn test_simple_set_limit() {
3441        use cyfs_base::*;
3442
3443        let mut content = ObjectMapSimpleContent::new(ObjectMapSimpleContentType::Set, 0);
3444
3445        let mut index: i32 = 0;
3446        loop {
3447            let chunk_id = ChunkId::calculate_sync(&index.to_be_bytes()).unwrap();
3448            let object_id = chunk_id.object_id();
3449            let ret = content.insert(&object_id).unwrap();
3450            assert!(ret);
3451
3452            let len = content.raw_measure(&None).unwrap();
3453            if len > u16::MAX as usize {
3454                println!("touch simple set limit! index ={}", index);
3455                break;
3456            }
3457
3458            index += 1;
3459        }
3460    }
3461
3462    fn hash_bytes(key: &[u8]) -> u64 {
3463        use std::collections::hash_map::DefaultHasher;
3464        use std::hash::Hasher;
3465
3466        let mut hasher = DefaultHasher::new();
3467        let mut sha256 = sha2::Sha256::new();
3468        sha256.input(key);
3469        hasher.write(&sha256.result());
3470        hasher.finish()
3471    }
3472
3473    #[test]
3474    fn test_hash() {
3475        let ret = hash_bytes("abc".as_bytes());
3476        println!("hash={}", ret);
3477    }
3478}