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 }
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 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
261impl 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#[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 step: usize,
402 result: ObjectMapIteratorResult,
404
405 depth: usize,
407 stack: Vec<IteratorPosition>,
408
409 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 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 self.step = step;
551
552 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 self.step = step;
580
581 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}