1#[derive(Clone)]
6pub struct Dict<K, V, Seq> {
7 live: std::collections::HashMap<K, Value<V, Seq>>,
8
9 removed: std::collections::HashMap<Seq, Seq>,
14}
15
16pub struct DictDiff<K, V: crate::Mergable, Seq> {
17 updates: Vec<Update<K, V, Seq>>,
18}
19
20impl<
21 K,
22 V: crate::Mergable,
23 SF: crate::SequenceFactory,
24> crate::Diff
25for DictDiff<K, V, crate::Sequence<SF>> {
26 fn is_empty(&self) -> bool {
27 self.updates.is_empty()
28 }
29
30 fn revert(mut self) -> Result<Self, crate::RevertError> {
31 crate::map_in_place(&mut self.updates, |update| Ok(match update {
32 Update::Del(_what, Some((k, v)), when) => Update::Up(when.undo()?, k, UpdateValue::New(v)),
33 Update::Del(what, None, when) => Update::Del(what, None, when),
34 Update::Up(what, k, v) => match v {
35 UpdateValue::New(v) => {
36 Update::Del(what.clone(), Some((k, v)), what.undo()?)
37 }
38 UpdateValue::Diff(diff) => {
39 Update::Up(what, k, UpdateValue::Diff(crate::Diff::revert(diff)?))
40 },
41 }
42 }))?;
43 Ok(self)
44 }
45}
46
47impl<
48 K: Clone,
49 V: crate::Mergable + Clone,
50 Seq: Clone,
51>
52 Clone for DictDiff<K, V, Seq>
53where
54 V::Diff: Clone,
55{
56 fn clone(&self) -> Self {
57 DictDiff {
58 updates: self.updates.clone(),
59 }
60 }
61}
62
63impl<
64 K: std::fmt::Debug,
65 V: crate::Mergable + std::fmt::Debug,
66 Seq: std::fmt::Debug
67>
68 std::fmt::Debug for DictDiff<K, V, Seq>
69where V::Diff: std::fmt::Debug
70{
71 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
72 write!(f, "DictDiff(")?;
73 self.updates.fmt(f)?;
74 write!(f, ")")
75 }
76}
77
78#[derive(Clone,Debug)]
79enum UpdateValue<N, D> {
80 New(N),
81 Diff(D),
82}
83
84#[derive(Clone,Debug)]
85enum Update<K, V: crate::Mergable, Seq> {
86 Del(
87 Seq,
89 Option<(K, V)>,
91 Seq,
93 ),
94 Up(
95 Seq,
97 K,
98 UpdateValue<V, V::Diff>,
99 ),
100}
101
102impl<
103 K: Clone + Eq + std::hash::Hash,
104 V: crate::Mergable,
105 SF: crate::SequenceFactory,
106>
107 Dict<K, V, crate::Sequence<SF>>
108{
109 pub fn entry(&mut self, key: K) -> DictEntry<K, V, SF> {
110 match self.live.entry(key) {
111 std::collections::hash_map::Entry::Occupied(entry) => {
112 DictEntry::Occupied(DictOccupiedEntry {
113 entry,
114 removed: &mut self.removed,
115 })
116 }
117 std::collections::hash_map::Entry::Vacant(entry) => {
118 DictEntry::Vacant(DictVacantEntry {
119 entry,
120 })
121 }
122 }
123 }
124
125 pub fn get<
126 Q: std::hash::Hash + Eq>
127 (&self, k: &Q) -> Option<&V>
128 where K: std::borrow::Borrow<Q>
129 {
130 self.live.get(k).map(|v| &v.value)
131 }
132
133 pub fn get_mut<
134 Q: std::hash::Hash + Eq>
135 (&mut self, k: &Q) -> Option<&mut V>
136 where K: std::borrow::Borrow<Q>
137 {
138 self.live.get_mut(k).map(|v| &mut v.value)
139 }
140
141 pub fn insert(&mut self, ctx: &mut crate::Context<SF>, k: K, v: V) {
150 self.entry(k).insert(ctx, v);
151 }
152
153 pub fn remove<Q: ?Sized>(&mut self, ctx: &mut crate::Context<SF>, k: K) -> Option<V>
160 where
161 K: std::borrow::Borrow<Q>,
162 Q: std::hash::Hash + Eq
163 {
164 if let DictEntry::Occupied(entry) = self.entry(k) {
165 Some(entry.remove(ctx))
166 } else {
167 None
168 }
169 }
170
171 pub fn len(&self) -> usize {
172 self.live.len()
173 }
174
175 pub fn is_empty(&self) -> bool {
176 self.live.is_empty()
177 }
178
179 pub fn iter(&self) -> DictIter<K, V, crate::Sequence<SF>> {
180 return DictIter(self.live.iter());
181 }
182
183 fn apply(&mut self,
184 updates: impl IntoIterator<Item=Update<K, V, crate::Sequence<SF>>>,
185 ) -> Result<(), crate::ApplyError> {
186 let mut unpurged_removals = std::collections::HashSet::new();
187 for update in updates {
188 match update {
189 Update::Del(what, value, when) => {
190 let removed_entry = match self.removed.entry(what) {
191 std::collections::hash_map::Entry::Occupied(mut entry) => {
192 if entry.get() < &when {
193 entry.insert(when.clone());
194 }
195 continue
196 }
197 std::collections::hash_map::Entry::Vacant(entry) => entry,
198 };
199
200 if let Some((k, _)) = value {
201 if let std::collections::hash_map::Entry::Occupied(entry) = self.live.entry(k) {
202 if entry.get().sequence == *removed_entry.key() {
203 eprintln!("remove");
204 entry.remove();
205 }
206 }
207 } else {
208 unpurged_removals.insert(removed_entry.key().clone());
209 }
210
211 removed_entry.insert(when.clone());
212 }
213 Update::Up(what, k, value) => {
214 match self.live.entry(k) {
215 std::collections::hash_map::Entry::Occupied(mut entry) => {
216 let slot = entry.get_mut();
217 if what > slot.sequence {
218 slot.sequence = what;
219 }
220 match value {
221 UpdateValue::Diff(d) => slot.value.apply(d)?,
222 UpdateValue::New(v) => slot.value.merge(v),
223 }
224 }
225 std::collections::hash_map::Entry::Vacant(entry) => {
226 if self.removed.contains_key(&what) {
227 continue
228 }
229
230 let UpdateValue::New(value) = value else {
231 return Err(crate::ApplyError::Missing(
232 "Target doesn't contain base value for diff.".into()))
233 };
234
235 entry.insert(Value{
236 sequence: what,
237 value,
238 });
239 }
240 }
241 }
242 }
243 }
244
245 if !unpurged_removals.is_empty() {
246 self.live.retain(|_, v| !unpurged_removals.contains(&v.sequence))
247 }
248
249 Ok(())
250 }
251}
252
253impl<
254 K: Clone + Eq + std::hash::Hash,
255 V: Clone + crate::Mergable<Seq=crate::Sequence<SF>>,
256 SF: crate::SequenceFactory,
257>
258 crate::Mergable for Dict<K, V, crate::Sequence<SF>>
259{
260 type Diff = DictDiff<K, V, crate::Sequence<SF>>;
261 type Seq = crate::Sequence<SF>;
262
263 fn merge(&mut self, that: Self) {
264 let removed = that.removed.into_iter()
265 .map(|(what, when)| Update::Del(what, None, when));
266 let live = that.live.into_iter()
267 .map(|(k, Value{sequence, value})| Update::Up(sequence, k, UpdateValue::New(value)));
268 self.apply(removed.chain(live)).unwrap()
269 }
270
271 fn diff(&self, that: &Self) -> Self::Diff {
272 let mut updates = Vec::<Update<K, V, crate::Sequence<SF>>>::new();
273
274 let mut deleted_seq = std::collections::HashMap::new();
275 for (what, when) in &self.removed {
276 if that.removed.get(what) >= Some(when) { continue }
277
278 let i = updates.len();
279 updates.push(Update::Del(what.clone(), None, when.clone()));
280 deleted_seq.insert(what, i);
281 }
282 if !deleted_seq.is_empty() {
283 for (k, v) in &that.live {
284 let Some(i) = deleted_seq.get(&v.sequence) else { continue };
285 let Update::Del(_, ref mut kv, _) = updates[*i] else { unreachable!() };
286 *kv = Some((k.clone(), v.value.clone()));
287 }
288 }
289
290 for (k, v) in &self.live {
291 if that.removed.contains_key(&v.sequence) { continue }
292 updates.push(
293 Update::Up(
294 v.sequence.clone(),
295 k.clone(),
296 match that.get(k) {
297 Some(known) => {
298 let diff = v.value.diff(known);
299 if crate::Diff::is_empty(&diff) { continue }
300 UpdateValue::Diff(diff)
301 }
302 None => UpdateValue::New(v.value.clone()),
303 }));
304 }
305
306 DictDiff { updates }
307 }
308
309 fn apply(&mut self, diff: Self::Diff) -> Result<(), crate::ApplyError> {
310 self.apply(diff.updates)
311 }
312
313 fn clean(&mut self, cutoff: &Self::Seq) {
314 for entry in self.live.values_mut() {
315 entry.value.clean(cutoff);
316 }
317 self.removed.retain(|_, seq| *seq >= *cutoff);
318 }
319}
320
321impl<
322 K,
323 V,
324 SF,
325>
326 Default for Dict<K, V, SF>
327{
328 fn default() -> Self {
329 Dict {
330 live: Default::default(),
331 removed: Default::default(),
332 }
333 }
334}
335
336impl<K: Eq + std::hash::Hash, V: PartialEq, Seq> PartialEq for Dict<K, V, Seq> {
337 fn eq(&self, that: &Self) -> bool {
338 self.live == that.live
339 }
340}
341
342impl<K: std::fmt::Debug, V: std::fmt::Debug, Seq> std::fmt::Debug for Dict<K, V, Seq> {
343 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
344 self.live.fmt(f)
345 }
346}
347
348#[derive(Clone)]
349struct Value<V, Seq> {
350 sequence: Seq,
351 value: V,
352}
353
354impl<V: PartialEq, Seq> PartialEq for Value<V, Seq> {
355 fn eq(&self, that: &Self) -> bool {
356 self.value == that.value
357 }
358}
359
360impl<V: std::fmt::Debug, Seq> std::fmt::Debug for Value<V, Seq> {
361 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
362 self.value.fmt(f)
364 }
365}
366
367pub enum DictEntry<'a, K: 'a, V: 'a, SF: crate::SequenceFactory> {
368 Occupied(DictOccupiedEntry<'a, K, V, SF>),
369 Vacant(DictVacantEntry<'a, K, V, SF>),
370}
371
372impl<'a,
373 K: 'a + Eq + std::hash::Hash,
374 V: 'a + crate::Mergable,
375 SF: crate::SequenceFactory
376>
377 DictEntry<'a, K, V, SF>
378{
379 pub fn insert(self, ctx: &'a mut crate::Context<SF>, v: V) -> &'a mut V {
380 match self {
381 DictEntry::Occupied(mut entry) => {
382 entry.insert(ctx, v);
383 entry.into_mut()
384 }
385 DictEntry::Vacant(entry) => entry.insert(ctx, v),
386 }
387 }
388
389 pub fn or_insert(self, ctx: &'a mut crate::Context<SF>, v: V) -> &'a mut V {
390 match self {
391 DictEntry::Occupied(mut entry) => {
392 entry.insert(ctx, v);
393 entry.into_mut()
394 }
395 DictEntry::Vacant(entry) => entry.insert(ctx, v),
396 }
397 }
398}
399
400pub struct DictOccupiedEntry<'a, K: 'a, V: 'a, SF: crate::SequenceFactory> {
401 entry: std::collections::hash_map::OccupiedEntry<'a, K, Value<V, crate::Sequence<SF>>>,
402 removed: &'a mut std::collections::HashMap<crate::Sequence<SF>, crate::Sequence<SF>>,
403}
404
405impl<'a,
406 K: 'a + Eq + std::hash::Hash,
407 V: 'a + crate::Mergable,
408 SF: crate::SequenceFactory
409>
410 DictOccupiedEntry<'a, K, V, SF>
411{
412 pub fn into_mut(self) -> &'a mut V {
413 &mut self.entry.into_mut().value
414 }
415
416 pub fn insert(&mut self, ctx: &'a mut crate::Context<SF>, v: V) {
417 self.entry.get_mut().sequence = ctx.next_sequence();
418 self.entry.get_mut().value.merge(v);
419 }
420
421 pub fn remove(self, ctx: &'a mut crate::Context<SF>) -> V {
422 let (_, Value{sequence, value}) = self.entry.remove_entry();
423 self.removed.insert(sequence, ctx.next_sequence());
424 value
425 }
426}
427
428pub struct DictVacantEntry<'a, K: 'a, V: 'a, SF: crate::SequenceFactory> {
429 entry: std::collections::hash_map::VacantEntry<'a, K, Value<V, crate::Sequence<SF>>>,
430}
431
432impl<'a, K: 'a, V: 'a, SF: crate::SequenceFactory> DictVacantEntry<'a, K, V, SF> {
433 pub fn insert(self, ctx: &'a mut crate::Context<SF>, value: V) -> &'a mut V {
434 &mut self.entry.insert(
435 Value {
436 sequence: ctx.next_sequence(),
437 value,
438 })
439 .value
440 }
441}
442
443pub struct DictIter<'a, K, V, Seq>(std::collections::hash_map::Iter<'a, K, Value<V, Seq>>);
444
445impl<'a, K, V, Seq> Iterator for DictIter<'a, K, V, Seq> {
446 type Item = (&'a K, &'a V);
447
448 fn next(&mut self) -> Option<Self::Item> {
449 self.0.next()
450 .map(|item| (item.0, &item.1.value))
451 }
452}
453
454impl<
455 'a,
456 K: Clone + Eq + std::hash::Hash,
457 V: crate::Mergable,
458 SF: crate::SequenceFactory,
459> IntoIterator for &'a Dict<K, V, crate::Sequence<SF>> {
460 type IntoIter = DictIter<'a, K, V, crate::Sequence<SF>>;
461 type Item = (&'a K, &'a V);
462
463 fn into_iter(self) -> Self::IntoIter {
464 self.iter()
465 }
466}
467
468pub struct DictIntoIter<K, V, Seq>(std::collections::hash_map::IntoIter<K, Value<V, Seq>>);
469
470impl<K, V, Seq> Iterator for DictIntoIter<K, V, Seq> {
471 type Item = (K, V);
472
473 fn next(&mut self) -> Option<Self::Item> {
474 self.0.next()
475 .map(|item| (item.0, item.1.value))
476 }
477}
478
479impl<
480 K: Clone + Eq + std::hash::Hash,
481 V: crate::Mergable,
482 SF: crate::SequenceFactory,
483> IntoIterator for Dict<K, V, crate::Sequence<SF>> {
484 type IntoIter = DictIntoIter<K, V, crate::Sequence<SF>>;
485 type Item = (K, V);
486
487 fn into_iter(self) -> Self::IntoIter {
488 DictIntoIter(self.live.into_iter())
489 }
490}
491
492#[test]
493fn test_dict() {
494 let mut ctx = crate::Context::default();
495
496 let one = crate::Cell::new(&mut ctx, "one");
497 let two = crate::Cell::new(&mut ctx, "two");
498
499 let result = crate::test::test_merge(&mut [&one, &two]);
500 assert_eq!(*result, "two");
501
502 let mut parent_l = Dict::default();
503 parent_l.insert(&mut ctx, 0, two.clone());
504
505 let mut parent_r = Dict::default();
506 parent_r.insert(&mut ctx, 0, one.clone());
507
508 let merged = crate::test::test_merge(&mut [&parent_l, &parent_r]);
509 assert_eq!(merged, parent_l);
510
511 let mut child_l = merged.clone();
512 child_l.insert(&mut ctx, 1, one.clone());
513
514 let mut child_r = merged;
515 child_r.insert(&mut ctx, 2, two.clone());
516
517 let merged = crate::test::test_merge(&mut [&parent_l, &parent_r, &child_l, &child_r]);
518 let mut expected = Dict::default();
519 expected.insert(&mut ctx, 0, two.clone());
520 expected.insert(&mut ctx, 1, one.clone());
521 expected.insert(&mut ctx, 2, two.clone());
522 assert_eq!(merged, expected);
523}
524
525#[test]
526fn test_dict_remove_old() {
527 let mut ctx = crate::Context::default();
528
529 let one = crate::Cell::new(&mut ctx, "one");
530 let two = crate::Cell::new(&mut ctx, "two");
531
532 let mut parent_l = Dict::default();
533 parent_l.insert(&mut ctx, 0, two.clone());
534
535 let mut parent_r = Dict::default();
536 parent_r.insert(&mut ctx, 0, one.clone());
537
538 parent_l.remove(&mut ctx, 0);
540
541 let merged = crate::test::test_merge(&mut [&parent_l, &parent_r]);
542 assert_eq!(merged, parent_r);
543}
544
545#[test]
546fn test_dict_remove_new() {
547 let mut ctx = crate::Context::default();
548
549 let one = crate::Cell::new(&mut ctx, "one");
550 let two = crate::Cell::new(&mut ctx, "two");
551
552 let mut parent_l = Dict::default();
553 parent_l.insert(&mut ctx, 0, two.clone());
554
555 let mut parent_r = Dict::default();
556 parent_r.insert(&mut ctx, 0, one.clone());
557
558 parent_r.remove(&mut ctx, 0);
560
561 let merged = crate::test::test_merge(&mut [&parent_l, &parent_r]);
562 assert_eq!(merged, parent_l);
563}
564
565#[test]
566fn test_dict_remove_merge_revive() {
567 let mut ctx = crate::Context::default();
568
569 let one = crate::Cell::new(&mut ctx, "one");
570 let two = crate::Cell::new(&mut ctx, "two");
571
572 let mut root = Dict::default();
573 root.insert(&mut ctx, 0, two.clone());
574
575 let mut child_insert = root.clone();
577 child_insert.insert(&mut ctx, 0, one.clone());
578
579 let mut child_remove = root.clone();
581 child_remove.remove(&mut ctx, 0);
582
583 let merged = crate::test::test_merge(&mut [&child_remove, &child_insert]);
584 assert_eq!(merged, child_insert);
585}
586
587#[test]
588fn test_undo_insert() {
589 let mut ctx = crate::Context::default();
590
591 let mut base = Dict::default();
592
593 let v = crate::Cell::new(&mut ctx, "one");
594 base.insert(&mut ctx, 1, v);
595
596 let mut updated = base.clone();
597
598 let v = crate::Cell::new(&mut ctx, "two");
599 updated.insert(&mut ctx, 2, v);
600 let diff_two = crate::Mergable::diff(&updated, &base);
601 crate::Mergable::apply(&mut base, diff_two.clone()).unwrap();
602
603 let initial = updated.clone();
604
605 let v = crate::Cell::new(&mut ctx, "three");
606 updated.insert(&mut ctx, 3, v);
607 let diff_three = crate::Mergable::diff(&updated, &base);
608
609 let revert = crate::Diff::revert(diff_two).unwrap();
610
611 let result = crate::test::test_apply(initial, &mut [
612 diff_three,
613 revert,
614 ]);
615
616 updated.remove(&mut ctx, 2);
617 assert_eq!(result, updated);
618}
619
620#[test]
621fn test_undo_remove() {
622 let mut ctx = crate::Context::default();
623
624 let mut base = Dict::default();
625
626 let v = crate::Cell::new(&mut ctx, "one");
627 base.insert(&mut ctx, 1, v);
628 let v = crate::Cell::new(&mut ctx, "two");
629 base.insert(&mut ctx, 2, v);
630
631 let mut updated = base.clone();
632
633 updated.remove(&mut ctx, 2);
634 let diff_two_remove = crate::Mergable::diff(&updated, &base);
635 crate::Mergable::apply(&mut base, diff_two_remove.clone()).unwrap();
636
637 let initial = base.clone();
638
639 let v = crate::Cell::new(&mut ctx, "three");
640 updated.insert(&mut ctx, 3, v);
641 let diff_three = crate::Mergable::diff(&updated, &base);
642
643 let revert = crate::Diff::revert(diff_two_remove.clone()).unwrap();
644
645 let result = crate::test::test_apply(initial, &mut [
646 diff_three,
647 revert,
648 ]);
649
650 let mut expected = Dict::default();
651 let v = crate::Cell::new(&mut ctx, "one");
652 expected.insert(&mut ctx, 1, v);
653 let v = crate::Cell::new(&mut ctx, "two");
654 expected.insert(&mut ctx, 2, v);
655 let v = crate::Cell::new(&mut ctx, "three");
656 expected.insert(&mut ctx, 3, v);
657 assert_eq!(result, expected);
658}
659
660#[test]
661fn test_undo_update() {
662 let mut ctx = crate::Context::default();
663
664 let mut base = Dict::default();
665
666 let mut sub = Dict::default();
667 let v = crate::Cell::new(&mut ctx, "one");
668 sub.insert(&mut ctx, 1, v);
669
670 base.insert(&mut ctx, (), sub);
671
672 let mut updated = base.clone();
673
674 let v = crate::Cell::new(&mut ctx, "two");
675 updated.get_mut(&()).unwrap().insert(&mut ctx, 2, v);
676
677 let diff_two = crate::Mergable::diff(&updated, &base);
678 let revert_diff_two = crate::Diff::revert(diff_two.clone()).unwrap();
679 dbg!(&updated, &base, &diff_two, &revert_diff_two);
680 crate::Mergable::apply(&mut base, diff_two).unwrap();
681
682 let v = crate::Cell::new(&mut ctx, "three");
683 updated.get_mut(&()).unwrap().insert(&mut ctx, 3, v);
684 let diff_three = crate::Mergable::diff(&updated, &base);
685
686 let result = crate::test::test_apply(base, &mut [
687 diff_three,
688 revert_diff_two,
689 ]);
690
691 let mut sub = Dict::default();
692 let v = crate::Cell::new(&mut ctx, "one");
693 sub.insert(&mut ctx, 1, v);
694 let v = crate::Cell::new(&mut ctx, "three");
695 sub.insert(&mut ctx, 3, v);
696 let mut expected = Dict::default();
697 expected.insert(&mut ctx, (), sub);
698 assert_eq!(result, expected);
699}
700
701#[test]
702fn test_undo_old_update() {
703 let mut ctx = crate::Context::default();
704
705 let mut base = Dict::default();
706
707 let mut sub = Dict::default();
708 let v = crate::Cell::new(&mut ctx, "one");
709 sub.insert(&mut ctx, 1, v);
710
711 base.insert(&mut ctx, (), sub);
712
713 let mut updated = base.clone();
714
715 let v = crate::Cell::new(&mut ctx, "two");
716 updated.get_mut(&()).unwrap().insert(&mut ctx, 2, v);
717
718 let diff_two = crate::Mergable::diff(&updated, &base);
719 let revert_diff_two = crate::Diff::revert(diff_two.clone()).unwrap();
720 crate::Mergable::apply(&mut base, diff_two).unwrap();
721
722 let v = crate::Cell::new(&mut ctx, "three");
723 updated.get_mut(&()).unwrap().insert(&mut ctx, 3, v);
724 let diff_three = crate::Mergable::diff(&updated, &base);
725
726 let result = crate::test::test_apply(base, &mut [
727 diff_three,
728 revert_diff_two,
729 ]);
730
731 let mut sub = Dict::default();
732 let v = crate::Cell::new(&mut ctx, "one");
733 sub.insert(&mut ctx, 1, v);
734 let v = crate::Cell::new(&mut ctx, "three");
735 sub.insert(&mut ctx, 3, v);
736 let mut expected = Dict::default();
737 expected.insert(&mut ctx, (), sub);
738 assert_eq!(result, expected);
739}
740
741#[test]
742fn test_iter() {
743 let mut ctx = crate::Context::default();
744
745 let one = crate::Cell::new(&mut ctx, "one");
746 let two = crate::Cell::new(&mut ctx, "two");
747 let three = crate::Cell::new(&mut ctx, "three");
748
749 let mut dict = Dict::default();
750 dict.insert(&mut ctx, 1, one);
751 dict.insert(&mut ctx, 2, two);
752 dict.remove(&mut ctx, 2);
753 dict.insert(&mut ctx, 3, three);
754
755 let mut seen = Vec::with_capacity(2);
756 for (k, v) in &dict {
757 seen.push((*k, **v));
758 }
759 seen.sort_unstable();
760 assert_eq!(seen, &[(1, "one"), (3, "three")]);
761}
762
763#[test]
764fn test_into_iter() {
765 let mut ctx = crate::Context::default();
766
767 let one = crate::Cell::new(&mut ctx, "one".to_string());
768 let two = crate::Cell::new(&mut ctx, "two".to_string());
769 let three = crate::Cell::new(&mut ctx, "three".to_string());
770
771 let mut dict = Dict::default();
772 dict.insert(&mut ctx, "1".to_string(), one);
773 dict.insert(&mut ctx, "2".to_string(), two);
774 dict.remove::<String>(&mut ctx, "2".to_string());
775 dict.insert(&mut ctx, "3".to_string(), three);
776
777 let mut seen = Vec::with_capacity(2);
778 for (k, v) in dict {
779 seen.push((k, v.into()));
780 }
781 seen.sort_unstable();
782 assert_eq!(seen, &[
783 ("1".to_string(), "one".to_string()),
784 ("3".to_string(), "three".to_string()),
785 ]);
786}
787
788#[test]
789fn test_clean() {
790 let mut ctx = crate::Context::default();
791
792 let mut d1 = Dict::default();
793 let one = crate::Cell::new(&mut ctx, "one");
794 d1.insert(&mut ctx, 1, one);
795
796 let d2 = d1.clone();
797
798 let seq_fork = ctx.next_sequence();
799
800 d1.remove(&mut ctx, 1);
801
802 let seq_remove = ctx.next_sequence();
803
804 assert_eq!(d1.removed.len(), 1);
805 crate::Mergable::clean(&mut d1, &seq_fork);
806 assert_eq!(d1.removed.len(), 1);
808
809 let result = crate::test::test_merge(&mut [&d1, &d2]);
811 assert_eq!(result.len(), 0);
812
813 crate::Mergable::clean(&mut d1, &seq_remove);
814 assert_eq!(d1.removed.len(), 0);
816
817 let result = crate::test::test_merge(&mut [&d1, &d2]);
819 assert_eq!(result.len(), 1);
820}