1use crate::{Digest, Hashable, Noun, NounDecode, NounEncode, Zeroable};
2use alloc::boxed::Box;
3use alloc::fmt::Debug;
4use alloc::vec;
5use alloc::vec::Vec;
6
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct ZSet<T> {
9 root: Zeroable<Box<Node<T>>>,
10}
11
12#[derive(Debug, Clone, PartialEq, Eq)]
13struct Node<T> {
14 value: T,
15 left: Zeroable<Box<Node<T>>>,
16 right: Zeroable<Box<Node<T>>>,
17}
18
19impl<T> Default for ZSet<T> {
20 fn default() -> Self {
21 Self::new()
22 }
23}
24
25impl<T> ZSet<T> {
26 pub fn new() -> Self {
27 ZSet {
28 root: Zeroable(None),
29 }
30 }
31}
32
33impl<T: NounEncode> ZSet<T> {
34 pub fn insert(&mut self, value: T) -> bool {
35 let (new_root, inserted) = Self::put(self.root.take(), value);
36 self.root = Zeroable(Some(new_root));
37 inserted
38 }
39
40 fn put(node: Option<Box<Node<T>>>, value: T) -> (Box<Node<T>>, bool) {
41 match node {
42 None => (
43 Box::new(Node {
44 value,
45 left: Zeroable(None),
46 right: Zeroable(None),
47 }),
48 true,
49 ),
50 Some(mut n) => {
51 if Self::tip_eq(&value, &n.value) {
52 return (n, false);
53 }
54 let go_left = Self::gor_tip(&value, &n.value);
55 if go_left {
56 let (new_left, inserted) = Self::put(n.left.take(), value);
57 n.left = Zeroable(Some(new_left));
58 if !Self::mor_tip(&n.value, &n.left.as_ref().unwrap().value) {
59 let mut new_root = n.left.take().unwrap();
61 n.left = Zeroable(new_root.right.take());
62 new_root.right = Zeroable(Some(n));
63 (new_root, inserted)
64 } else {
65 (n, inserted)
66 }
67 } else {
68 let (new_right, inserted) = Self::put(n.right.take(), value);
69 n.right = Zeroable(Some(new_right));
70 if !Self::mor_tip(&n.value, &n.right.as_ref().unwrap().value) {
71 let mut new_root = n.right.take().unwrap();
73 n.right = Zeroable(new_root.left.take());
74 new_root.left = Zeroable(Some(n));
75 (new_root, inserted)
76 } else {
77 (n, inserted)
78 }
79 }
80 }
81 }
82 }
83
84 fn tip_eq(a: &T, b: &T) -> bool {
85 a.to_noun().hash() == b.to_noun().hash()
86 }
87
88 fn gor_tip(a: &T, b: &T) -> bool {
89 a.to_noun().hash().to_bytes() < b.to_noun().hash().to_bytes()
90 }
91
92 fn mor_tip(a: &T, b: &T) -> bool {
93 Self::double_tip(a).to_bytes() < Self::double_tip(b).to_bytes()
94 }
95
96 fn double_tip(a: &T) -> Digest {
97 (a.to_noun().hash(), a.to_noun().hash()).hash()
98 }
99}
100
101impl<T: NounEncode> core::iter::FromIterator<T> for ZSet<T> {
102 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
103 let mut set = ZSet::new();
104 for item in iter {
105 set.insert(item);
106 }
107 set
108 }
109}
110
111impl<T: NounEncode + Hashable> Hashable for ZSet<T> {
112 fn hash(&self) -> Digest {
113 fn hash_node<T: NounEncode + Hashable>(node: &Option<Box<Node<T>>>) -> Digest {
114 match node {
115 None => 0.hash(),
116 Some(n) => {
117 let left_hash = hash_node(&n.left);
118 let right_hash = hash_node(&n.right);
119 (&n.value, (left_hash, right_hash)).hash()
120 }
121 }
122 }
123 hash_node(&self.root)
124 }
125}
126
127impl<T: NounEncode> NounEncode for ZSet<T> {
128 fn to_noun(&self) -> Noun {
129 fn visit<T: NounEncode>(node: &Zeroable<Box<Node<T>>>) -> Noun {
130 match node.as_ref() {
131 None => 0.to_noun(),
132 Some(n) => {
133 let left_hash = visit(&n.left);
134 let right_hash = visit(&n.right);
135 (&n.value, (left_hash, right_hash)).to_noun()
136 }
137 }
138 }
139 visit(&self.root)
140 }
141}
142
143impl<T: NounDecode> NounDecode for Node<T> {
144 fn from_noun(noun: &Noun) -> Option<Self> {
145 let (value, left, right) = NounDecode::from_noun(noun)?;
146 Some(Self { value, left, right })
147 }
148}
149
150impl<T: NounDecode> NounDecode for ZSet<T> {
151 fn from_noun(noun: &Noun) -> Option<Self> {
152 let root: Zeroable<Box<Node<T>>> = NounDecode::from_noun(noun)?;
153 Some(Self { root })
154 }
155}
156
157pub struct ZSetIntoIterator<T> {
158 stack: Vec<Box<Node<T>>>,
159}
160
161impl<T> Iterator for ZSetIntoIterator<T> {
162 type Item = T;
163
164 fn next(&mut self) -> Option<Self::Item> {
165 let cur = self.stack.pop()?;
166 if let Some(n) = cur.left.0 {
167 self.stack.push(n);
168 }
169 if let Some(n) = cur.right.0 {
170 self.stack.push(n);
171 }
172 Some(cur.value)
173 }
174}
175
176impl<T> IntoIterator for ZSet<T> {
177 type Item = T;
178 type IntoIter = ZSetIntoIterator<T>;
179
180 fn into_iter(self) -> Self::IntoIter {
181 let mut stack = vec![];
182 if let Some(n) = self.root.0 {
183 stack.push(n);
184 }
185 ZSetIntoIterator { stack }
186 }
187}
188
189impl<T: NounEncode> From<ZSet<T>> for Vec<T> {
190 fn from(set: ZSet<T>) -> Self {
191 set.into_iter().collect()
192 }
193}
194
195#[cfg(test)]
196mod tests {
197 use super::*;
198 use alloc::string::{String, ToString};
199
200 #[test]
201 fn test_zset_encode_decode() {
202 let mut zm = ZSet::<String>::new();
203 zm.insert("ver".to_string());
204 zm.insert("ve2".to_string());
205 let zm_noun = zm.to_noun();
206 let zm_decode = ZSet::<String>::from_noun(&zm_noun).unwrap();
207 assert_eq!(Vec::from(zm), Vec::from(zm_decode));
208 }
209}