cyfs_base/objects/object_map/
iterator.rs

1use super::cache::*;
2use super::diff::*;
3use super::object_map::*;
4use crate::*;
5
6use serde::Serialize;
7
8#[derive(Clone, Debug, RawEncode, RawDecode, Eq, PartialEq, Serialize)]
9pub struct ObjectMapDiffMapItem {
10    pub prev: Option<ObjectId>,
11    pub altered: Option<ObjectId>,
12    pub diff: Option<ObjectId>,
13}
14
15impl ObjectMapDiffMapItem {
16    pub fn action(&self) -> ObjectMapDiffAction {
17        if self.prev.is_none() {
18            assert!(self.altered.is_some());
19            ObjectMapDiffAction::Add
20        } else if self.altered.is_none() {
21            assert!(self.prev.is_some());
22            ObjectMapDiffAction::Remove
23        } else {
24            ObjectMapDiffAction::Alter
25        }
26    }
27}
28
29impl std::fmt::Display for ObjectMapDiffMapItem {
30    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31        write!(
32            f,
33            "prev={:?}, altered={:?}, diff={:?}",
34            self.prev, self.altered, self.diff
35        )
36    }
37}
38
39#[derive(Clone, Debug, RawEncode, RawDecode, Eq, PartialEq, Ord, PartialOrd, Serialize)]
40pub struct ObjectMapDiffSetItem {
41    pub prev: Option<ObjectId>,
42    pub altered: Option<ObjectId>,
43}
44
45impl ObjectMapDiffSetItem {
46    pub fn as_slice(&self) -> &[u8] {
47        match &self.prev {
48            Some(value) => value.as_slice(),
49            None => self.altered.as_ref().unwrap().as_slice(),
50        }
51    }
52
53    pub fn action(&self) -> ObjectMapDiffAction {
54        if self.prev.is_none() {
55            assert!(self.altered.is_some());
56            ObjectMapDiffAction::Add
57        } else if self.altered.is_none() {
58            assert!(self.prev.is_some());
59            ObjectMapDiffAction::Remove
60        } else {
61            unreachable!();
62        }
63    }
64}
65
66impl std::fmt::Display for ObjectMapDiffSetItem {
67    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
68        if let Some(id) = self.prev {
69            write!(f, "-{}", id)
70        } else if let Some(id) = self.altered {
71            write!(f, "+{}", id)
72        } else {
73            write!(f, "None")
74        }
75        // write!(f, "prev={:?}, altered={:?}", self.prev, self.altered)
76    }
77}
78
79pub trait IntoObjectMapContentItem {
80    fn into_content(self, key: Option<&str>) -> ObjectMapContentItem;
81}
82
83impl IntoObjectMapContentItem for ObjectMapDiffMapItem {
84    fn into_content(self, key: Option<&str>) -> ObjectMapContentItem {
85        ObjectMapContentItem::DiffMap((key.unwrap().to_owned(), self))
86    }
87}
88impl IntoObjectMapContentItem for ObjectMapDiffSetItem {
89    fn into_content(self, key: Option<&str>) -> ObjectMapContentItem {
90        assert!(key.is_none());
91        ObjectMapContentItem::DiffSet(self)
92    }
93}
94impl IntoObjectMapContentItem for ObjectId {
95    fn into_content(self, key: Option<&str>) -> ObjectMapContentItem {
96        match key {
97            Some(key) => ObjectMapContentItem::Map((key.to_owned(), self)),
98            None => ObjectMapContentItem::Set(self),
99        }
100    }
101}
102
103#[derive(Debug, Eq, PartialEq,)]
104pub enum ObjectMapContentItem {
105    DiffMap((String, ObjectMapDiffMapItem)),
106    Map((String, ObjectId)),
107    DiffSet(ObjectMapDiffSetItem),
108    Set(ObjectId),
109}
110
111impl ObjectMapContentItem {
112    pub fn content_type(&self) -> ObjectMapSimpleContentType {
113        match &self {
114            Self::Map(_) => ObjectMapSimpleContentType::Map,
115            Self::DiffMap(_) => ObjectMapSimpleContentType::DiffMap,
116            Self::Set(_) => ObjectMapSimpleContentType::Set,
117            Self::DiffSet(_) => ObjectMapSimpleContentType::DiffSet,
118        }
119    }
120
121    pub fn into_map_item(self) -> (String, ObjectId) {
122        match self {
123            Self::Map(value) => value,
124            _ => unreachable!(),
125        }
126    }
127
128    pub fn into_diff_map_item(self) -> (String, ObjectMapDiffMapItem) {
129        match self {
130            Self::DiffMap(value) => value,
131            _ => unreachable!(),
132        }
133    }
134
135    pub fn into_set_item(self) -> ObjectId {
136        match self {
137            Self::Set(value) => value,
138            _ => unreachable!(),
139        }
140    }
141
142    pub fn into_diff_set_item(self) -> ObjectMapDiffSetItem {
143        match self {
144            Self::DiffSet(value) => value,
145            _ => unreachable!(),
146        }
147    }
148}
149
150impl std::fmt::Display for ObjectMapContentItem {
151    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
152        match &self {
153            ObjectMapContentItem::Map((key, value)) => {
154                write!(f, "({}: {}),", key, value)?;
155            }
156            ObjectMapContentItem::DiffMap((key, value)) => {
157                match value.action() {
158                    ObjectMapDiffAction::Add => match &value.altered {
159                        Some(id) => write!(f, "(+ {}: {}),", key, id)?,
160                        None => write!(f, "(+ {}: None),", key)?,
161                    },
162                    ObjectMapDiffAction::Remove => match &value.prev {
163                        Some(id) => write!(f, "(- {}: {}),", key, id)?,
164                        None => write!(f, "(- {}: None),", key)?,
165                    },
166                    ObjectMapDiffAction::Alter => {
167                        // action返回Alter情况下,prev和altered一定不为空
168                        write!(
169                            f,
170                            "({}: {} -> {}),",
171                            key,
172                            value.prev.as_ref().unwrap(),
173                            value.altered.as_ref().unwrap()
174                        )?;
175                    }
176                }
177            }
178            ObjectMapContentItem::Set(value) => {
179                write!(f, "({}),", value)?;
180            }
181            ObjectMapContentItem::DiffSet(value) => match value.action() {
182                ObjectMapDiffAction::Add => match &value.altered {
183                    Some(id) => {
184                        write!(f, "(+ {}),", id)?;
185                    }
186                    None => write!(f, "(+ None),")?,
187                },
188                ObjectMapDiffAction::Remove => match &value.prev {
189                    Some(id) => {
190                        write!(f, "(- {}),", id)?;
191                    }
192                    None => write!(f, "(- None),")?,
193                },
194                _ => {
195                    unreachable!();
196                }
197            },
198        }
199
200        Ok(())
201    }
202}
203
204pub struct ObjectMapContentList {
205    pub list: Vec<ObjectMapContentItem>,
206}
207
208impl std::fmt::Display for ObjectMapContentList {
209    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
210        for item in &self.list {
211            write!(f, "{},", item)?;
212        }
213
214        Ok(())
215    }
216}
217
218impl ObjectMapContentList {
219    pub fn new(capacity: usize) -> Self {
220        Self {
221            list: Vec::with_capacity(capacity),
222        }
223    }
224
225    pub fn push_key_value(&mut self, key: &str, value: impl IntoObjectMapContentItem) {
226        let item = value.into_content(Some(key));
227        self.list.push(item);
228    }
229
230    pub fn push_value(&mut self, value: impl IntoObjectMapContentItem) {
231        let item = value.into_content(None);
232        self.list.push(item);
233    }
234
235    pub fn take(&mut self) -> ObjectMapContentList {
236        let mut ret = ObjectMapContentList::new(0);
237        std::mem::swap(&mut ret.list, &mut self.list);
238
239        ret
240    }
241}
242
243#[derive(Debug, Clone)]
244pub enum SetIteratorPostion {
245    DiffSet(ObjectMapDiffSetItem),
246    Set(ObjectId),
247}
248
249impl From<ObjectId> for SetIteratorPostion {
250    fn from(value: ObjectId) -> Self {
251        Self::Set(value)
252    }
253}
254
255impl From<ObjectMapDiffSetItem> for SetIteratorPostion {
256    fn from(value: ObjectMapDiffSetItem) -> Self {
257        Self::DiffSet(value)
258    }
259}
260
261/*
262impl Into<SetIteratorPostion> for ObjectId {
263    fn into(self) -> SetIteratorPostion {
264        SetIteratorPostion::Set(self)
265    }
266}
267
268impl Into<SetIteratorPostion> for ObjectMapDiffSetItem {
269    fn into(self) -> SetIteratorPostion {
270        SetIteratorPostion::DiffSet(self)
271    }
272}
273*/
274
275impl From<SetIteratorPostion> for ObjectId {
276    fn from(value: SetIteratorPostion) -> Self {
277        match value {
278            SetIteratorPostion::Set(v) => v,
279            _ => unreachable!(),
280        }
281    }
282}
283
284impl From<SetIteratorPostion> for ObjectMapDiffSetItem {
285    fn from(value: SetIteratorPostion) -> Self {
286        match value {
287            SetIteratorPostion::DiffSet(v) => v,
288            _ => unreachable!(),
289        }
290    }
291}
292
293/*
294impl Into<ObjectId> for SetIteratorPostion {
295    fn into(self) -> ObjectId {
296        match self {
297            Self::Set(v) => v,
298            _ => unreachable!(),
299        }
300    }
301}
302
303impl Into<ObjectMapDiffSetItem> for SetIteratorPostion {
304    fn into(self) -> ObjectMapDiffSetItem {
305        match self {
306            Self::DiffSet(v) => v,
307            _ => unreachable!(),
308        }
309    }
310}
311*/
312
313#[derive(Debug, Clone)]
314pub enum IteratorPosition {
315    Hub(Option<u16>),
316    SimpleSet(Option<SetIteratorPostion>),
317    SimpleMap(Option<String>),
318}
319
320impl IteratorPosition {
321    pub fn into_hub(self) -> Option<u16> {
322        match self {
323            Self::Hub(value) => value,
324            _ => unreachable!(),
325        }
326    }
327
328    pub fn into_simple_map(self) -> Option<String> {
329        match self {
330            Self::SimpleMap(value) => value,
331            _ => unreachable!(),
332        }
333    }
334
335    pub fn into_simple_set(self) -> Option<SetIteratorPostion> {
336        match self {
337            Self::SimpleSet(value) => value,
338            _ => unreachable!(),
339        }
340    }
341}
342struct HubContentIterator {
343    object_id: ObjectId,
344    pos: Option<String>,
345}
346
347enum ObjectMapIteratorResult {
348    Iterator(ObjectMapContentList),
349    Skip(usize),
350}
351
352impl ObjectMapIteratorResult {
353    pub fn len(&self) -> usize {
354        match self {
355            Self::Iterator(r) => r.list.len(),
356            Self::Skip(count) => *count,
357        }
358    }
359
360    pub fn is_empty(&self) -> bool {
361        self.len() == 0
362    }
363
364    pub fn push_key_value(&mut self, key: &str, value: impl IntoObjectMapContentItem) {
365        match self {
366            Self::Iterator(r) => r.push_key_value(key, value),
367            Self::Skip(count) => *count += 1,
368        }
369    }
370
371    pub fn push_value(&mut self, value: impl IntoObjectMapContentItem) {
372        match self {
373            Self::Iterator(r) => r.push_value(value),
374            Self::Skip(count) => *count += 1,
375        }
376    }
377
378    pub fn take_iterator_result(&mut self) -> ObjectMapContentList {
379        match self {
380            Self::Iterator(r) => r.take(),
381            Self::Skip(_) => unreachable!(),
382        }
383    }
384
385    pub fn take_skip_result(&mut self) -> usize {
386        match self {
387            Self::Skip(count) => {
388                let ret = *count;
389                *count = 0;
390                ret
391            }
392            Self::Iterator(_) => unreachable!(),
393        }
394    }
395}
396
397pub struct ObjectMapIterator {
398    pub cache: ObjectMapOpEnvCacheRef,
399
400    // 每次步进的元素个数
401    step: usize,
402    // 读取到的元素个数
403    result: ObjectMapIteratorResult,
404
405    // 保存深度遍历状态的栈
406    depth: usize,
407    stack: Vec<IteratorPosition>,
408
409    // 是否结束
410    is_end: bool,
411}
412
413impl ObjectMapIterator {
414    pub fn new(skip: bool, target: &ObjectMap, cache: ObjectMapOpEnvCacheRef) -> Self {
415        let result = if skip {
416            ObjectMapIteratorResult::Skip(0)
417        } else {
418            ObjectMapIteratorResult::Iterator(ObjectMapContentList::new(1))
419        };
420
421        let mut it = Self {
422            cache,
423            step: 1,
424            result,
425            depth: 0,
426            stack: vec![],
427            is_end: false,
428        };
429
430        it.push_empty_pos(target.mode(), target.content_type());
431        it
432    }
433
434    // skip -> intertor
435    pub fn into_iterator(mut self) -> Self {
436        match self.result {
437            ObjectMapIteratorResult::Skip(_) => {
438                self.result = ObjectMapIteratorResult::Iterator(ObjectMapContentList::new(1));
439            }
440            ObjectMapIteratorResult::Iterator(_) => unreachable!(),
441        }
442
443        self
444    }
445
446    pub(crate) fn mark_end(&mut self) {
447        assert!(!self.is_end);
448        self.is_end = true;
449    }
450
451    pub fn is_end(&self) -> bool {
452        self.is_end
453    }
454
455    pub fn step(&self) -> usize {
456        self.step
457    }
458
459    pub fn depth(&self) -> usize {
460        self.depth
461    }
462
463    pub fn reset_depth(&mut self) {
464        self.depth = 0;
465    }
466
467    pub fn current_pos(&self) -> IteratorPosition {
468        assert!(self.stack.len() > self.depth);
469        self.stack[self.depth].clone()
470    }
471
472    pub fn update_pos(&mut self, depth: usize, pos: IteratorPosition) {
473        assert!(self.stack.len() > depth);
474        self.stack[depth] = pos;
475    }
476
477    pub fn is_enough(&self) -> bool {
478        let total = self.result.len();
479        if total < self.step {
480            false
481        } else {
482            assert_eq!(total, self.step);
483            true
484        }
485    }
486
487    pub fn inc_depth(
488        &mut self,
489        mode: ObjectMapContentMode,
490        content_type: ObjectMapSimpleContentType,
491    ) {
492        self.depth += 1;
493        if self.depth == self.stack.len() {
494            self.push_empty_pos(mode, content_type);
495        }
496    }
497
498    fn push_empty_pos(
499        &mut self,
500        mode: ObjectMapContentMode,
501        content_type: ObjectMapSimpleContentType,
502    ) {
503        let new_pos = match mode {
504            ObjectMapContentMode::Simple => match content_type {
505                ObjectMapSimpleContentType::Map | ObjectMapSimpleContentType::DiffMap => {
506                    IteratorPosition::SimpleMap(None)
507                }
508                ObjectMapSimpleContentType::Set | ObjectMapSimpleContentType::DiffSet => {
509                    IteratorPosition::SimpleSet(None)
510                }
511            },
512            ObjectMapContentMode::Hub => IteratorPosition::Hub(None),
513        };
514
515        self.stack.push(new_pos);
516    }
517
518    pub fn dec_depth(&mut self) {
519        assert!(self.depth > 0);
520        assert_eq!(self.depth, self.stack.len() - 1);
521
522        self.depth -= 1;
523        self.stack.pop().unwrap();
524    }
525
526    pub fn push_key_value(&mut self, key: &str, value: impl IntoObjectMapContentItem) {
527        self.result.push_key_value(key, value);
528    }
529
530    pub fn push_value(&mut self, value: impl IntoObjectMapContentItem) {
531        self.result.push_value(value);
532    }
533
534    pub async fn next(
535        &mut self,
536        target: &ObjectMap,
537        step: usize,
538    ) -> BuckyResult<ObjectMapContentList> {
539        assert!(self.result.is_empty());
540
541        if self.is_end() {
542            return Ok(ObjectMapContentList::new(0));
543        }
544
545        if step == 0 {
546            return Ok(ObjectMapContentList::new(0));
547        }
548
549        // 每次迭代可以指定不同的step
550        self.step = step;
551
552        // 重置当前的遍历深度
553        self.reset_depth();
554
555        {
556            target.next(self).await?;
557        }
558
559        let result = self.result.take_iterator_result().take();
560        if result.list.len() < self.step {
561            self.mark_end();
562        }
563
564        Ok(result)
565    }
566
567    pub async fn skip(&mut self, target: &ObjectMap, step: usize) -> BuckyResult<usize> {
568        assert!(self.result.is_empty());
569
570        if self.is_end() {
571            return Ok(0);
572        }
573
574        if step == 0 {
575            return Ok(0);
576        }
577
578        // 每次迭代可以指定不同的step
579        self.step = step;
580
581        // 重置当前的遍历深度
582        self.reset_depth();
583
584        {
585            target.next(self).await?;
586        }
587
588        let count = self.result.take_skip_result();
589        if count < self.step {
590            self.mark_end();
591        }
592
593        Ok(count)
594    }
595}
596
597pub struct ObjectMapBindIterator {
598    target: ObjectMapRef,
599    iterator: ObjectMapIterator,
600}
601
602impl ObjectMapBindIterator {
603    pub async fn new_with_target(target: ObjectMapRef, cache: ObjectMapOpEnvCacheRef) -> Self {
604        let iterator = {
605            let obj = target.lock().await;
606            ObjectMapIterator::new(false, &obj, cache)
607        };
608
609        Self { target, iterator }
610    }
611
612    pub async fn next(&mut self, step: usize) -> BuckyResult<ObjectMapContentList> {
613        let target = self.target.clone();
614        let obj = target.lock().await;
615        self.iterator.next(&obj, step).await
616    }
617}
618
619impl std::ops::Deref for ObjectMapBindIterator {
620    type Target = ObjectMapIterator;
621    fn deref(&self) -> &ObjectMapIterator {
622        &self.iterator
623    }
624}
625
626#[cfg(test)]
627mod test {
628    use super::super::cache::*;
629    use super::*;
630
631    use async_std::sync::Mutex as AsyncMutex;
632    use std::collections::HashSet;
633    use std::sync::Arc;
634
635    async fn test_iterator() {
636        let noc = ObjectMapMemoryNOCCache::new();
637        let root_cache = ObjectMapRootMemoryCache::new_default_ref(None, noc);
638        let cache = ObjectMapOpEnvMemoryCache::new_ref(root_cache.clone());
639
640        let owner = ObjectId::default();
641        let mut map = ObjectMap::new(
642            ObjectMapSimpleContentType::Map,
643            Some(owner.clone()),
644            Some(owner.clone()),
645        )
646        .no_create_time()
647        .build();
648
649        let mut origin_keys = HashSet::new();
650        for i in 0..1000 {
651            let key = format!("test_map_{:0>3}", i);
652            let object_id = ObjectId::default();
653            info!("begin insert_with_key: {}", key);
654            map.insert_with_key(&cache, &key, &object_id).await.unwrap();
655            info!("end insert_with_key: {}", key);
656
657            let ret = origin_keys.insert(key);
658            assert!(ret);
659        }
660
661        let obj = Arc::new(AsyncMutex::new(map));
662        let mut it = ObjectMapBindIterator::new_with_target(obj, cache).await;
663        let mut step = 0;
664        let mut got_keys = HashSet::new();
665        while !it.is_end() {
666            let list = it.next(step + 1).await.unwrap();
667            info!("list: {} {:?}", step, list.list);
668            step += 1;
669            for item in list.list {
670                let ret = got_keys.insert(item.into_map_item().0);
671                assert!(ret);
672            }
673        }
674
675        assert_eq!(origin_keys, got_keys);
676        info!("iterate complete, count={}", got_keys.len());
677    }
678
679    #[test]
680    fn test() {
681        crate::init_simple_log("test-object-map-iterator", Some("debug"));
682        async_std::task::block_on(async move {
683            test_iterator().await;
684        });
685    }
686}