1use std::cell::Cell;
13use std::cmp::Ordering;
14use std::rc::Rc;
15
16use crate::lang::hash::JavaHash;
17use crate::lang::protocol::{
18 HashType, IAssoc, IColl, IConj, ICount, IDisplay, IDissoc, IEmpty, IEquality, IFind, IHash,
19 IIndexedKV, ILookup, IMetadata, IMutable, INth, IObjType, IPersistent, IToMutable,
20 IToPersistent, MetaType, ObjType,
21};
22
23#[derive(Debug, Clone, Copy, PartialEq, Eq)]
25enum Color {
26 Red,
27 Black,
28 DoubleBlack,
29}
30use Color::{Black, DoubleBlack, Red};
31
32#[derive(Debug, Clone)]
34enum Link<K, V> {
35 Empty,
37 DoubleEmpty,
39 Full(Rc<Node<K, V>>),
40}
41
42#[derive(Debug, Clone)]
43pub struct Node<K, V> {
44 pub key: K,
45 pub value: V,
46 color: Color,
47 left: Link<K, V>,
48 right: Link<K, V>,
49 size: usize,
50}
51
52impl<K, V> Link<K, V> {
53 fn color(&self) -> Color {
54 match self {
55 Link::Empty => Black,
56 Link::DoubleEmpty => DoubleBlack,
57 Link::Full(node) => node.color,
58 }
59 }
60 fn size(&self) -> usize {
61 match self {
62 Link::Full(node) => node.size,
63 _ => 0,
64 }
65 }
66}
67
68fn node<K, V>(color: Color, left: Link<K, V>, key: K, value: V, right: Link<K, V>) -> Link<K, V> {
70 Link::Full(Rc::new(Node {
71 size: left.size() + right.size() + 1,
72 color,
73 left,
74 key,
75 value,
76 right,
77 }))
78}
79fn red<K, V>(left: Link<K, V>, key: K, value: V, right: Link<K, V>) -> Link<K, V> {
80 node(Red, left, key, value, right)
81}
82fn black<K, V>(left: Link<K, V>, key: K, value: V, right: Link<K, V>) -> Link<K, V> {
83 node(Black, left, key, value, right)
84}
85
86fn redden<K: Clone, V: Clone>(link: &Link<K, V>) -> Link<K, V> {
88 match link {
89 Link::Full(n)
90 if n.color == Black && n.left.color() == Black && n.right.color() == Black =>
91 {
92 red(
93 n.left.clone(),
94 n.key.clone(),
95 n.value.clone(),
96 n.right.clone(),
97 )
98 }
99 _ => link.clone(),
100 }
101}
102fn blacken<K: Clone, V: Clone>(link: &Link<K, V>) -> Link<K, V> {
104 match link {
105 Link::Full(n) if n.color == Red => black(
106 n.left.clone(),
107 n.key.clone(),
108 n.value.clone(),
109 n.right.clone(),
110 ),
111 _ => link.clone(),
112 }
113}
114fn unblacken<K: Clone, V: Clone>(link: &Link<K, V>) -> Link<K, V> {
117 match link {
118 Link::DoubleEmpty => Link::Empty,
119 Link::Full(n) if n.color == DoubleBlack => black(
120 n.left.clone(),
121 n.key.clone(),
122 n.value.clone(),
123 n.right.clone(),
124 ),
125 _ => link.clone(),
126 }
127}
128
129fn put<K: Clone + Ord, V: Clone>(root: &Link<K, V>, key: K, value: V) -> Link<K, V> {
132 blacken(&put_rec(root, key, value))
133}
134fn put_rec<K: Clone + Ord, V: Clone>(link: &Link<K, V>, key: K, value: V) -> Link<K, V> {
135 match link {
136 Link::Empty => red(Link::Empty, key, value, Link::Empty),
138 Link::DoubleEmpty => black(Link::Empty, key, value, Link::Empty),
139 Link::Full(n) => match key.cmp(&n.key) {
140 Ordering::Less => balance(node(
141 n.color,
142 put_rec(&n.left, key, value),
143 n.key.clone(),
144 n.value.clone(),
145 n.right.clone(),
146 )),
147 Ordering::Greater => balance(node(
148 n.color,
149 n.left.clone(),
150 n.key.clone(),
151 n.value.clone(),
152 put_rec(&n.right, key, value),
153 )),
154 Ordering::Equal => node(n.color, n.left.clone(), key, value, n.right.clone()),
155 },
156 }
157}
158
159fn remove<K: Clone + Ord, V: Clone>(root: &Link<K, V>, key: &K) -> Link<K, V> {
162 let result = remove_rec(&redden(root), key);
163 if result.size() == root.size() {
164 root.clone()
165 } else {
166 result
167 }
168}
169fn remove_rec<K: Clone + Ord, V: Clone>(link: &Link<K, V>, key: &K) -> Link<K, V> {
170 let Link::Full(n) = link else {
171 return link.clone();
172 };
173 match key.cmp(&n.key) {
174 Ordering::Less => rotate(node(
175 n.color,
176 remove_rec(&n.left, key),
177 n.key.clone(),
178 n.value.clone(),
179 n.right.clone(),
180 )),
181 Ordering::Greater => rotate(node(
182 n.color,
183 n.left.clone(),
184 n.key.clone(),
185 n.value.clone(),
186 remove_rec(&n.right, key),
187 )),
188 Ordering::Equal => {
189 if n.size == 1 {
190 if n.color == Black {
192 Link::DoubleEmpty
193 } else {
194 Link::Empty
195 }
196 } else if n.right.size() == 0 {
197 blacken(&n.left)
198 } else {
199 let min = leftmost(&n.right);
200 rotate(node(
201 n.color,
202 n.left.clone(),
203 min.key.clone(),
204 min.value.clone(),
205 remove_min(&n.right),
206 ))
207 }
208 }
209 }
210}
211
212fn leftmost<K, V>(link: &Link<K, V>) -> &Rc<Node<K, V>> {
214 let Link::Full(n) = link else {
215 unreachable!("min of an empty subtree")
216 };
217 match &n.left {
218 Link::Full(_) => leftmost(&n.left),
219 _ => n,
220 }
221}
222
223fn remove_min<K: Clone, V: Clone>(link: &Link<K, V>) -> Link<K, V> {
225 let Link::Full(n) = link else {
226 return link.clone();
227 };
228 if n.left.size() == 0 {
229 return match n.color {
230 Red => Link::Empty,
231 _ if n.right.size() == 0 => Link::DoubleEmpty,
232 _ => blacken(&n.right),
233 };
234 }
235 rotate(node(
236 n.color,
237 remove_min(&n.left),
238 n.key.clone(),
239 n.value.clone(),
240 n.right.clone(),
241 ))
242}
243
244fn balance<K: Clone, V: Clone>(link: Link<K, V>) -> Link<K, V> {
247 let Link::Full(_) = link else {
248 return link;
249 };
250 match link.color() {
251 Black => balance_black(&link),
252 DoubleBlack => balance_double_black(&link),
253 Red => link,
254 }
255}
256
257fn balance_black<K: Clone, V: Clone>(link: &Link<K, V>) -> Link<K, V> {
259 let Link::Full(n) = link else {
260 return link.clone();
261 };
262 if let Link::Full(l) = &n.left {
263 if l.color == Red {
264 if let Link::Full(ll) = &l.left {
266 if ll.color == Red {
267 return red(
268 blacken(&l.left),
269 l.key.clone(),
270 l.value.clone(),
271 black(
272 l.right.clone(),
273 n.key.clone(),
274 n.value.clone(),
275 n.right.clone(),
276 ),
277 );
278 }
279 }
280 if let Link::Full(lr) = &l.right {
282 if lr.color == Red {
283 return red(
284 black(
285 l.left.clone(),
286 l.key.clone(),
287 l.value.clone(),
288 lr.left.clone(),
289 ),
290 lr.key.clone(),
291 lr.value.clone(),
292 black(
293 lr.right.clone(),
294 n.key.clone(),
295 n.value.clone(),
296 n.right.clone(),
297 ),
298 );
299 }
300 }
301 }
302 }
303 if let Link::Full(r) = &n.right {
304 if r.color == Red {
305 if let Link::Full(rl) = &r.left {
307 if rl.color == Red {
308 return red(
309 black(
310 n.left.clone(),
311 n.key.clone(),
312 n.value.clone(),
313 rl.left.clone(),
314 ),
315 rl.key.clone(),
316 rl.value.clone(),
317 black(
318 rl.right.clone(),
319 r.key.clone(),
320 r.value.clone(),
321 r.right.clone(),
322 ),
323 );
324 }
325 }
326 if let Link::Full(rr) = &r.right {
328 if rr.color == Red {
329 return red(
330 black(
331 n.left.clone(),
332 n.key.clone(),
333 n.value.clone(),
334 r.left.clone(),
335 ),
336 r.key.clone(),
337 r.value.clone(),
338 blacken(&r.right),
339 );
340 }
341 }
342 }
343 }
344 link.clone()
345}
346
347fn balance_double_black<K: Clone, V: Clone>(link: &Link<K, V>) -> Link<K, V> {
349 let Link::Full(n) = link else {
350 return link.clone();
351 };
352 if let Link::Full(l) = &n.left {
354 if l.color == Red {
355 if let Link::Full(lr) = &l.right {
356 if lr.color == Red {
357 return black(
358 black(
359 l.left.clone(),
360 l.key.clone(),
361 l.value.clone(),
362 lr.left.clone(),
363 ),
364 lr.key.clone(),
365 lr.value.clone(),
366 black(
367 lr.right.clone(),
368 n.key.clone(),
369 n.value.clone(),
370 n.right.clone(),
371 ),
372 );
373 }
374 }
375 }
376 }
377 if let Link::Full(r) = &n.right {
379 if r.color == Red {
380 if let Link::Full(rl) = &r.left {
381 if rl.color == Red {
382 return black(
383 black(
384 n.left.clone(),
385 n.key.clone(),
386 n.value.clone(),
387 rl.left.clone(),
388 ),
389 rl.key.clone(),
390 rl.value.clone(),
391 black(
392 rl.right.clone(),
393 r.key.clone(),
394 r.value.clone(),
395 r.right.clone(),
396 ),
397 );
398 }
399 }
400 }
401 }
402 link.clone()
403}
404
405fn rotate<K: Clone, V: Clone>(link: Link<K, V>) -> Link<K, V> {
408 let Link::Full(n) = &link else {
409 return link;
410 };
411 match n.color {
412 Red => {
413 if n.left.color() == DoubleBlack && n.right.color() == Black {
415 let Link::Full(r) = &n.right else {
416 unreachable!("sibling of a double black must be an internal node")
417 };
418 return balance(black(
419 red(
420 unblacken(&n.left),
421 n.key.clone(),
422 n.value.clone(),
423 r.left.clone(),
424 ),
425 r.key.clone(),
426 r.value.clone(),
427 r.right.clone(),
428 ));
429 }
430 if n.right.color() == DoubleBlack && n.left.color() == Black {
432 let Link::Full(l) = &n.left else {
433 unreachable!("sibling of a double black must be an internal node")
434 };
435 return balance(black(
436 l.left.clone(),
437 l.key.clone(),
438 l.value.clone(),
439 red(
440 l.right.clone(),
441 n.key.clone(),
442 n.value.clone(),
443 unblacken(&n.right),
444 ),
445 ));
446 }
447 }
448 Black => {
449 if n.left.color() == DoubleBlack && n.right.color() == Black {
451 let Link::Full(r) = &n.right else {
452 unreachable!("sibling of a double black must be an internal node")
453 };
454 return balance(node(
455 DoubleBlack,
456 red(
457 unblacken(&n.left),
458 n.key.clone(),
459 n.value.clone(),
460 r.left.clone(),
461 ),
462 r.key.clone(),
463 r.value.clone(),
464 r.right.clone(),
465 ));
466 }
467 if n.left.color() == Black && n.right.color() == DoubleBlack {
469 let Link::Full(l) = &n.left else {
470 unreachable!("sibling of a double black must be an internal node")
471 };
472 return balance(node(
473 DoubleBlack,
474 l.left.clone(),
475 l.key.clone(),
476 l.value.clone(),
477 red(
478 l.right.clone(),
479 n.key.clone(),
480 n.value.clone(),
481 unblacken(&n.right),
482 ),
483 ));
484 }
485 if n.left.color() == DoubleBlack && n.right.color() == Red {
488 let Link::Full(r) = &n.right else {
489 unreachable!("sibling of a double black must be an internal node")
490 };
491 if let Link::Full(rl) = &r.left {
492 if rl.color == Black {
493 return black(
494 balance(black(
495 red(
496 unblacken(&n.left),
497 n.key.clone(),
498 n.value.clone(),
499 rl.left.clone(),
500 ),
501 rl.key.clone(),
502 rl.value.clone(),
503 rl.right.clone(),
504 )),
505 r.key.clone(),
506 r.value.clone(),
507 r.right.clone(),
508 );
509 }
510 }
511 }
512 if n.left.color() == Red && n.right.color() == DoubleBlack {
515 let Link::Full(l) = &n.left else {
516 unreachable!("sibling of a double black must be an internal node")
517 };
518 if let Link::Full(lr) = &l.right {
519 if lr.color == Black {
520 return black(
521 l.left.clone(),
522 l.key.clone(),
523 l.value.clone(),
524 balance(black(
525 lr.left.clone(),
526 lr.key.clone(),
527 lr.value.clone(),
528 red(
529 lr.right.clone(),
530 n.key.clone(),
531 n.value.clone(),
532 unblacken(&n.right),
533 ),
534 )),
535 );
536 }
537 }
538 }
539 }
540 DoubleBlack => {}
541 }
542 link.clone()
543}
544
545fn floor_index<K: Ord, V>(link: &Link<K, V>, key: &K, offset: usize) -> Option<usize> {
547 let Link::Full(n) = link else {
548 return None;
549 };
550 match key.cmp(&n.key) {
551 Ordering::Greater => {
552 floor_index(&n.right, key, offset + n.left.size() + 1).or(Some(offset + n.left.size()))
553 }
554 Ordering::Less => floor_index(&n.left, key, offset),
555 Ordering::Equal => Some(offset + n.left.size()),
556 }
557}
558
559fn ceil_index<K: Ord, V>(link: &Link<K, V>, key: &K, offset: usize) -> Option<usize> {
561 let Link::Full(n) = link else {
562 return None;
563 };
564 match key.cmp(&n.key) {
565 Ordering::Greater => ceil_index(&n.right, key, offset + n.left.size() + 1),
566 Ordering::Less => ceil_index(&n.left, key, offset).or(Some(offset + n.left.size())),
567 Ordering::Equal => Some(offset + n.left.size()),
568 }
569}
570
571fn slice<K: Clone + Ord, V: Clone>(link: &Link<K, V>, min: &K, max: &K) -> Link<K, V> {
574 let Link::Full(n) = link else {
575 return link.clone();
576 };
577 match (n.key.cmp(min), n.key.cmp(max)) {
578 (Ordering::Less, _) => slice(&n.right, min, max),
579 (_, Ordering::Greater) => slice(&n.left, min, max),
580 _ => rotate(node(
581 n.color,
582 slice(&n.left, min, max),
583 n.key.clone(),
584 n.value.clone(),
585 slice(&n.right, min, max),
586 )),
587 }
588}
589
590fn map_values<K: Clone, V, U>(link: &Link<K, V>, f: &impl Fn(&K, &V) -> U) -> Link<K, U> {
592 match link {
593 Link::Empty => Link::Empty,
594 Link::DoubleEmpty => Link::DoubleEmpty,
595 Link::Full(n) => node(
596 n.color,
597 map_values(&n.left, f),
598 n.key.clone(),
599 f(&n.key, &n.value),
600 map_values(&n.right, f),
601 ),
602 }
603}
604
605#[cfg(test)]
608fn check_invariant<K, V>(link: &Link<K, V>) -> usize {
609 assert_ne!(link.color(), DoubleBlack, "double black left in tree");
610 let Link::Full(n) = link else {
611 return 1;
612 };
613 assert!(
614 n.color != Red || (n.left.color() != Red && n.right.color() != Red),
615 "red-red violation"
616 );
617 let left_depth = check_invariant(&n.left);
618 let right_depth = check_invariant(&n.right);
619 assert_eq!(left_depth, right_depth, "black-height violation");
620 assert_eq!(
621 n.size,
622 n.left.size() + n.right.size() + 1,
623 "size record violation"
624 );
625 left_depth + usize::from(n.color == Black)
626}
627
628#[derive(Debug, Clone)]
629pub struct Standard<K, V> {
630 metadata: Option<Rc<crate::lang::data::Metadata>>,
631 root: Link<K, V>,
632}
633impl<K, V> Default for Standard<K, V> {
634 fn default() -> Self {
635 Self {
636 metadata: None,
637 root: Link::Empty,
638 }
639 }
640}
641impl<K: Clone + Ord, V: Clone> Standard<K, V> {
642 pub fn new() -> Self {
643 Self::default()
644 }
645 pub fn len(&self) -> usize {
646 self.root.size()
647 }
648 pub fn is_empty(&self) -> bool {
649 self.root.size() == 0
650 }
651 pub fn get(&self, key: &K) -> Option<&V> {
652 self.find_entry(key).map(|(_, value)| value)
653 }
654 pub fn find_entry(&self, key: &K) -> Option<(&K, &V)> {
656 let mut cursor = &self.root;
657 while let Link::Full(current) = cursor {
658 match key.cmp(¤t.key) {
659 Ordering::Less => cursor = ¤t.left,
660 Ordering::Greater => cursor = ¤t.right,
661 Ordering::Equal => return Some((¤t.key, ¤t.value)),
662 }
663 }
664 None
665 }
666 pub fn assoc_value(&self, key: K, value: V) -> Self {
667 Self {
668 metadata: self.metadata.clone(),
669 root: put(&self.root, key, value),
670 }
671 }
672 pub fn dissoc_value(&self, key: &K) -> Self {
673 Self {
674 metadata: self.metadata.clone(),
675 root: remove(&self.root, key),
676 }
677 }
678 pub fn iter(&self) -> Iter<'_, K, V> {
679 Iter::new(&self.root)
680 }
681 pub fn nth_entry(&self, mut index: usize) -> Option<&Node<K, V>> {
683 let mut cursor = &self.root;
684 while let Link::Full(current) = cursor {
685 let left_size = current.left.size();
686 if index < left_size {
687 cursor = ¤t.left;
688 } else if index == left_size {
689 return Some(current);
690 } else {
691 index -= left_size + 1;
692 cursor = ¤t.right;
693 }
694 }
695 None
696 }
697 pub fn index_of_key(&self, key: &K) -> Option<usize> {
699 let mut offset = 0;
700 let mut cursor = &self.root;
701 while let Link::Full(current) = cursor {
702 match key.cmp(¤t.key) {
703 Ordering::Less => cursor = ¤t.left,
704 Ordering::Greater => {
705 offset += current.left.size() + 1;
706 cursor = ¤t.right;
707 }
708 Ordering::Equal => return Some(offset + current.left.size()),
709 }
710 }
711 None
712 }
713 pub fn inclusive_floor_index(&self, key: &K) -> Option<usize> {
715 floor_index(&self.root, key, 0)
716 }
717 pub fn ceil_index(&self, key: &K) -> Option<usize> {
719 ceil_index(&self.root, key, 0)
720 }
721 pub fn slice(&self, min: &K, max: &K) -> Self {
722 Self {
723 metadata: self.metadata.clone(),
724 root: slice(&self.root, min, max),
725 }
726 }
727 pub fn map_values<U: Clone>(&self, f: impl Fn(&K, &V) -> U) -> Standard<K, U> {
728 Standard {
729 metadata: self.metadata.clone(),
730 root: map_values(&self.root, &f),
731 }
732 }
733}
734impl<K: Clone + Ord, V: Clone> FromIterator<(K, V)> for Standard<K, V> {
735 fn from_iter<T: IntoIterator<Item = (K, V)>>(it: T) -> Self {
736 it.into_iter()
737 .fold(Self::new(), |m, (k, v)| m.assoc_value(k, v))
738 }
739}
740impl<K: Clone + Ord, V: Clone> ICount for Standard<K, V> {
741 fn count(&self) -> usize {
742 self.len()
743 }
744}
745impl<K: Clone + Ord, V: Clone> IFind<K> for Standard<K, V> {
746 type Output = (K, V);
747 fn find(&self, k: &K) -> Option<Self::Output> {
748 self.find_entry(k).map(|(k, v)| (k.clone(), v.clone()))
749 }
750}
751impl<K: Clone + Ord, V: Clone> ILookup<K, V> for Standard<K, V> {
752 type Keys = std::vec::IntoIter<K>;
753 type Values = std::vec::IntoIter<V>;
754 fn keys(&self) -> Self::Keys {
755 self.iter()
756 .map(|(k, _)| k.clone())
757 .collect::<Vec<_>>()
758 .into_iter()
759 }
760 fn vals(&self) -> Self::Values {
761 self.iter()
762 .map(|(_, v)| v.clone())
763 .collect::<Vec<_>>()
764 .into_iter()
765 }
766}
767impl<K: Clone + Ord, V: Clone> IAssoc<K, V> for Standard<K, V> {
768 type Output = Self;
769 fn assoc(&self, k: K, v: V) -> Self {
770 self.assoc_value(k, v)
771 }
772}
773impl<K: Clone + Ord, V: Clone> IDissoc<K> for Standard<K, V> {
774 type Output = Self;
775 fn dissoc(&self, k: &K) -> Self {
776 self.dissoc_value(k)
777 }
778}
779impl<K: Clone + Ord, V: Clone> INth<Node<K, V>> for Standard<K, V> {
780 fn nth(&self, index: usize) -> Option<&Node<K, V>> {
781 self.nth_entry(index)
782 }
783}
784impl<K: Clone + Ord, V: Clone + PartialEq> IIndexedKV<K, V> for Standard<K, V> {
785 fn index_of_key(&self, key: &K) -> Option<usize> {
786 Standard::index_of_key(self, key)
787 }
788 fn index_of_val(&self, value: &V) -> Option<usize> {
789 self.iter().position(|(_, candidate)| candidate == value)
790 }
791}
792impl<K: Clone + Ord, V: Clone> IEmpty for Standard<K, V> {
793 type Output = Self;
794 fn empty(&self) -> Self {
795 Self::new().with_meta(self.metadata.clone())
796 }
797}
798impl<K: Clone + Ord, V: Clone> IMetadata for Standard<K, V> {
799 type Metadata = Rc<crate::lang::data::Metadata>;
800 fn meta(&self) -> Option<&Self::Metadata> {
801 self.metadata.as_ref()
802 }
803 fn with_meta(&self, metadata: Option<Self::Metadata>) -> Self {
804 Self {
805 metadata,
806 ..self.clone()
807 }
808 }
809
810 fn metatype(&self) -> MetaType {
811 MetaType::Map
812 }
813}
814impl<K: Clone + Ord, V: Clone> IPersistent for Standard<K, V> {}
815impl<K: Clone + Ord, V: Clone> IntoIterator for Standard<K, V> {
816 type Item = (K, V);
817 type IntoIter = std::vec::IntoIter<(K, V)>;
818 fn into_iter(self) -> Self::IntoIter {
819 self.iter()
820 .map(|(k, v)| (k.clone(), v.clone()))
821 .collect::<Vec<_>>()
822 .into_iter()
823 }
824}
825impl<K: Clone + Ord, V: Clone> IConj<(K, V)> for Standard<K, V> {
826 type Output = Self;
827 fn conj(&self, (k, v): (K, V)) -> Self {
828 self.assoc_value(k, v)
829 }
830}
831impl<K: Clone + Ord, V: Clone + PartialEq> IEquality for Standard<K, V> {
832 fn equality(&self, other: &Self) -> bool {
833 self.len() == other.len() && self.iter().all(|(k, v)| other.get(k) == Some(v))
834 }
835}
836impl<K: Clone + Ord + std::fmt::Debug, V: Clone + std::fmt::Debug> IDisplay for Standard<K, V> {
837 fn display(&self) -> String {
838 format!(
839 "{{{}}}",
840 self.iter()
841 .map(|(k, v)| format!("{k:?} {v:?}"))
842 .collect::<Vec<_>>()
843 .join(" ")
844 )
845 }
846}
847impl<K: Clone + Ord + std::hash::Hash + JavaHash, V: Clone + std::hash::Hash + JavaHash> IHash
848 for Standard<K, V>
849{
850 fn hash_calc(&self, hash_type: HashType) -> u64 {
851 crate::lang::hash::compose_unordered(
854 "MAP",
855 self.iter().map(|(k, v)| {
856 crate::lang::hash::compose_entry(k.java_hash(hash_type), v.java_hash(hash_type))
857 }),
858 ) as u64
859 }
860}
861impl<K: Clone + Ord + std::fmt::Debug, V: Clone + std::fmt::Debug> IObjType for Standard<K, V> {
862 fn obj_type(&self) -> ObjType {
863 ObjType::Map
864 }
865}
866impl<K, V> IColl<(K, V)> for Standard<K, V>
867where
868 K: Clone + Ord + std::hash::Hash + JavaHash + std::fmt::Debug,
869 V: Clone + PartialEq + std::hash::Hash + JavaHash + std::fmt::Debug,
870{
871 fn start_string(&self) -> &'static str {
872 "{"
873 }
874 fn end_string(&self) -> &'static str {
875 "}"
876 }
877}
878impl<K: Clone + Ord, V: Clone> IToMutable for Standard<K, V> {
879 type Mutable = Mutable<K, V>;
880 fn to_mutable(&self) -> Self::Mutable {
881 Mutable {
882 editable: Cell::new(true),
883 map: self.clone(),
884 }
885 }
886}
887
888pub struct Iter<'a, K, V> {
891 stack: Vec<&'a Node<K, V>>,
892}
893impl<'a, K, V> Iter<'a, K, V> {
894 fn new(root: &'a Link<K, V>) -> Self {
895 let mut it = Self { stack: Vec::new() };
896 it.push_left(root);
897 it
898 }
899 fn push_left(&mut self, mut link: &'a Link<K, V>) {
900 while let Link::Full(current) = link {
901 self.stack.push(&**current);
902 link = ¤t.left;
903 }
904 }
905}
906impl<'a, K, V> Iterator for Iter<'a, K, V> {
907 type Item = (&'a K, &'a V);
908 fn next(&mut self) -> Option<Self::Item> {
909 let n = self.stack.pop()?;
910 self.push_left(&n.right);
911 Some((&n.key, &n.value))
912 }
913}
914
915#[derive(Debug, Clone)]
916pub struct Mutable<K, V> {
917 editable: Cell<bool>,
918 map: Standard<K, V>,
919}
920impl<K: Clone + Ord, V: Clone> Mutable<K, V> {
921 fn check(&self) {
922 assert!(
923 self.editable.get(),
924 "mutable sorted map used after to_persistent"
925 )
926 }
927 pub fn assoc(&mut self, k: K, v: V) -> &mut Self {
928 self.check();
929 self.map = self.map.assoc_value(k, v);
930 self
931 }
932 pub fn dissoc(&mut self, k: &K) -> &mut Self {
933 self.check();
934 self.map = self.map.dissoc_value(k);
935 self
936 }
937}
938impl<K: Clone + Ord, V: Clone> std::ops::Deref for Mutable<K, V> {
939 type Target = Standard<K, V>;
940 fn deref(&self) -> &Self::Target {
941 self.check();
942 &self.map
943 }
944}
945impl<K, V> IMutable for Mutable<K, V> {}
946impl<K: Clone + Ord, V: Clone> IToPersistent for Mutable<K, V> {
947 type Persistent = Standard<K, V>;
948 fn to_persistent(&mut self) -> Self::Persistent {
949 self.check();
950 self.editable.set(false);
951 self.map.clone()
952 }
953}
954
955#[cfg(test)]
956mod tests {
957 use super::{check_invariant, Link, Standard};
958 use std::collections::BTreeMap;
959
960 struct Rng(u64);
962 impl Rng {
963 fn next(&mut self) -> u64 {
964 self.0 = self.0.wrapping_add(0x9E3779B97F4A7C15);
965 let mut z = self.0;
966 z = (z ^ (z >> 30)).wrapping_mul(0xBF58476D1CE4E5B9);
967 z = (z ^ (z >> 27)).wrapping_mul(0x94D049BB133111EB);
968 z ^ (z >> 31)
969 }
970 fn below(&mut self, n: u64) -> u64 {
971 self.next() % n
972 }
973 }
974
975 #[test]
976 fn tree_updates_slices_maps_empty_and_mutable_preserve_metadata() {
977 use crate::lang::protocol::{IEmpty, IMetadata, IToMutable, IToPersistent};
978 let map = [(1, 10), (2, 20), (3, 30)]
979 .into_iter()
980 .collect::<Standard<_, _>>()
981 .with_meta(Some(crate::lang::data::Metadata::document("doc")));
982 assert_eq!(
983 map.assoc_value(4, 40).meta().map(|m| m.doc().unwrap()),
984 Some("doc")
985 );
986 assert_eq!(
987 map.dissoc_value(&1).meta().map(|m| m.doc().unwrap()),
988 Some("doc")
989 );
990 assert_eq!(
991 map.slice(&1, &2).meta().map(|m| m.doc().unwrap()),
992 Some("doc")
993 );
994 assert_eq!(
995 map.map_values(|_, value| value + 1)
996 .meta()
997 .map(|m| m.doc().unwrap()),
998 Some("doc")
999 );
1000 assert_eq!(map.empty().meta().map(|m| m.doc().unwrap()), Some("doc"));
1001 let mut mutable = map.to_mutable();
1002 mutable.assoc(4, 40);
1003 assert_eq!(
1004 mutable.to_persistent().meta().map(|m| m.doc().unwrap()),
1005 Some("doc")
1006 );
1007 }
1008
1009 #[test]
1010 fn stays_sorted_indexed_and_persistent() {
1011 let a = [(5, "e"), (1, "a"), (3, "c"), (2, "b"), (4, "d")]
1012 .into_iter()
1013 .collect::<Standard<_, _>>();
1014 assert_eq!(
1015 a.iter().map(|(k, _)| *k).collect::<Vec<_>>(),
1016 vec![1, 2, 3, 4, 5]
1017 );
1018 assert_eq!(a.index_of_key(&3), Some(2));
1019 assert_eq!(a.nth_entry(2).map(|node| node.key), Some(3));
1020 assert_eq!(a.inclusive_floor_index(&0), None);
1021 assert_eq!(a.inclusive_floor_index(&6), Some(4));
1022 assert_eq!(a.ceil_index(&0), Some(0));
1023 let b = a.dissoc_value(&3);
1024 assert!(b.get(&3).is_none());
1025 assert!(a.get(&3).is_some());
1026 }
1027
1028 #[test]
1029 fn churn_matches_btree_map_model() {
1030 for seed in 0..4u64 {
1031 let mut rng = Rng(seed);
1032 let mut map = Standard::new();
1033 let mut model = BTreeMap::new();
1034 for step in 0..2000 {
1035 let key = rng.below(400) as i64;
1036 if rng.below(5) < 3 {
1037 let value = rng.next() as i64;
1038 map = map.assoc_value(key, value);
1039 model.insert(key, value);
1040 } else {
1041 map = map.dissoc_value(&key);
1042 model.remove(&key);
1043 }
1044 check_invariant(&map.root);
1045 assert_eq!(map.len(), model.len(), "seed {seed} step {step}");
1046 assert_eq!(map.get(&key), model.get(&key), "seed {seed} step {step}");
1047 if step % 100 == 99 {
1048 assert!(
1049 map.iter().eq(model.iter()),
1050 "seed {seed} step {step} contents"
1051 );
1052 }
1053 }
1054 assert!(map.iter().eq(model.iter()), "seed {seed} final contents");
1055 }
1056 }
1057
1058 #[test]
1059 fn rank_ops_match_btree_map_model() {
1060 let mut rng = Rng(42);
1061 let mut map = Standard::new();
1062 let mut model = BTreeMap::new();
1063 for _ in 0..300 {
1064 let key = rng.below(200) as i64;
1065 map = map.assoc_value(key, key * 10);
1066 model.insert(key, key * 10);
1067 }
1068 let keys: Vec<i64> = model.keys().copied().collect();
1069 for probe in -5..205i64 {
1071 assert_eq!(
1072 map.index_of_key(&probe),
1073 keys.iter().position(|k| *k == probe),
1074 "index_of {probe}"
1075 );
1076 assert_eq!(
1077 map.inclusive_floor_index(&probe),
1078 keys.iter().rposition(|k| *k <= probe),
1079 "floor {probe}"
1080 );
1081 assert_eq!(
1082 map.ceil_index(&probe),
1083 keys.iter().position(|k| *k >= probe),
1084 "ceil {probe}"
1085 );
1086 }
1087 for (i, key) in keys.iter().enumerate() {
1088 assert_eq!(map.nth_entry(i).map(|node| node.key), Some(*key), "nth {i}");
1089 assert_eq!(
1090 map.nth_entry(i).map(|node| node.value),
1091 Some(*key * 10),
1092 "nth value {i}"
1093 );
1094 }
1095 assert!(map.nth_entry(keys.len()).is_none());
1096 }
1097
1098 #[test]
1099 fn slice_matches_btree_range_and_stays_usable() {
1100 let mut rng = Rng(7);
1101 let mut map = Standard::new();
1102 let mut model = BTreeMap::new();
1103 for _ in 0..200 {
1104 let key = rng.below(500) as i64;
1105 map = map.assoc_value(key, key);
1106 model.insert(key, key);
1107 }
1108 for _ in 0..200 {
1109 let a = rng.below(550) as i64 - 25;
1110 let b = rng.below(550) as i64 - 25;
1111 let (min, max) = if a <= b { (a, b) } else { (b, a) };
1112 let sliced = map.slice(&min, &max);
1113 assert_eq!(
1114 sliced.len(),
1115 model.range(min..=max).count(),
1116 "slice [{min},{max}]"
1117 );
1118 assert!(
1119 sliced.iter().eq(model.range(min..=max)),
1120 "slice [{min},{max}] contents"
1121 );
1122 let mut grown = sliced;
1125 let mut grown_model: BTreeMap<i64, i64> =
1126 model.range(min..=max).map(|(k, v)| (*k, *v)).collect();
1127 for _ in 0..20 {
1128 let key = rng.below(550) as i64 - 25;
1129 grown = grown.assoc_value(key, key);
1130 grown_model.insert(key, key);
1131 }
1132 assert!(
1133 grown.iter().eq(grown_model.iter()),
1134 "slice [{min},{max}] grown"
1135 );
1136 }
1137 assert!(map.slice(&1000, &2000).is_empty());
1138 }
1139
1140 #[test]
1141 fn map_values_maps_every_entry_preserving_order() {
1142 use crate::lang::protocol::IMetadata;
1143 let map = (0..50i64)
1144 .map(|k| (k, k))
1145 .collect::<Standard<_, _>>()
1146 .with_meta(Some(crate::lang::data::Metadata::document("doc")));
1147 let mapped = map.map_values(|k, v| v + k);
1148 check_invariant(&mapped.root);
1149 assert!(mapped
1150 .iter()
1151 .map(|(k, v)| (*k, *v))
1152 .eq((0..50i64).map(|k| (k, k + k))));
1153 assert_eq!(mapped.meta().map(|m| m.doc().unwrap()), Some("doc"));
1154 }
1155
1156 #[test]
1157 fn sequential_deletes_force_double_black_paths() {
1158 let mut map = Standard::new();
1160 for key in 0..400i64 {
1161 map = map.assoc_value(key, key);
1162 check_invariant(&map.root);
1163 }
1164 for key in (0..400i64).rev() {
1165 map = map.dissoc_value(&key);
1166 check_invariant(&map.root);
1167 assert_eq!(map.len() as i64, key);
1168 assert!(map.get(&key).is_none());
1169 if key % 50 == 0 {
1170 assert!(map.iter().map(|(k, _)| *k).eq(0..key));
1171 }
1172 }
1173 assert!(map.is_empty());
1174 assert!(matches!(map.root, Link::Empty));
1175 }
1176
1177 #[test]
1178 fn random_delete_order_down_to_empty() {
1179 let mut rng = Rng(99);
1180 let mut keys: Vec<i64> = (0..300).collect();
1181 for i in (1..keys.len()).rev() {
1182 let j = rng.below(i as u64 + 1) as usize;
1183 keys.swap(i, j);
1184 }
1185 let mut map: Standard<i64, i64> = (0..300i64).map(|k| (k, k)).collect();
1186 let mut model: BTreeMap<i64, i64> = (0..300i64).map(|k| (k, k)).collect();
1187 for key in keys {
1188 map = map.dissoc_value(&key);
1189 model.remove(&key);
1190 check_invariant(&map.root);
1191 assert_eq!(map.len(), model.len());
1192 if map.len() % 50 == 0 {
1193 assert!(map.iter().eq(model.iter()));
1194 }
1195 }
1196 assert!(map.is_empty());
1197 assert!(matches!(map.root, Link::Empty));
1198 }
1199
1200 #[test]
1201 fn iterator_yields_sorted_order_and_exhausts() {
1202 let map: Standard<i64, i64> = [(3, 3), (1, 1), (2, 2)].into_iter().collect();
1203 let mut it = map.iter();
1204 assert_eq!(it.next(), Some((&1, &1)));
1205 assert_eq!(it.next(), Some((&2, &2)));
1206 assert_eq!(it.next(), Some((&3, &3)));
1207 assert_eq!(it.next(), None);
1208 assert_eq!(it.next(), None);
1209 let empty: Standard<i64, i64> = Standard::new();
1210 assert_eq!(empty.iter().next(), None);
1211 let big: Standard<i64, i64> = (0..10_000i64).map(|k| (k, k)).collect();
1213 assert!(big.iter().map(|(k, _)| *k).eq(0..10_000));
1214 assert_eq!(big.len(), 10_000);
1215 }
1216
1217 #[test]
1218 fn transient_round_trip_matches_persistent() {
1219 use crate::lang::protocol::{IToMutable, IToPersistent};
1220 let mut rng = Rng(5);
1221 let mut persistent = Standard::new();
1222 let mut transient = Standard::new().to_mutable();
1223 for _ in 0..500 {
1224 let key = rng.below(300) as i64;
1225 if rng.below(2) == 0 {
1226 persistent = persistent.assoc_value(key, key);
1227 transient.assoc(key, key);
1228 } else {
1229 persistent = persistent.dissoc_value(&key);
1230 transient.dissoc(&key);
1231 }
1232 }
1233 let back = transient.to_persistent();
1234 assert_eq!(back.len(), persistent.len());
1235 assert!(back.iter().eq(persistent.iter()));
1236 check_invariant(&back.root);
1237 }
1238}