bucky_objects/objects/object_map/
object_map.rs

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