cljrs_value/collections/
transient_set.rs1use crate::hash::hash_combine_unordered;
2use crate::{ClojureHash, PersistentHashSet, Value, ValueError, ValueResult};
3use std::sync::Mutex;
4
5#[derive(Debug)]
6pub struct TransientSet {
7 set: Mutex<rpds::HashTrieSetSync<Value>>,
8 persisted: Mutex<bool>,
9}
10
11impl TransientSet {
12 pub fn new() -> Self {
13 TransientSet {
14 set: Mutex::new(Default::default()),
15 persisted: Mutex::new(false),
16 }
17 }
18
19 pub fn new_from_set(set: &rpds::HashTrieSetSync<Value>) -> TransientSet {
20 TransientSet {
21 set: Mutex::new(set.clone()),
22 persisted: Mutex::new(false),
23 }
24 }
25
26 pub fn conj(&self, value: Value) -> ValueResult<()> {
27 if *self.persisted.lock().unwrap() {
28 return Err(ValueError::TransientAlreadyPersisted);
29 }
30 self.set.lock().unwrap().insert_mut(value.clone());
31 Ok(())
32 }
33
34 pub fn disj(&self, value: &Value) -> ValueResult<()> {
35 if *self.persisted.lock().unwrap() {
36 return Err(ValueError::TransientAlreadyPersisted);
37 }
38 self.set.lock().unwrap().remove_mut(value);
39 Ok(())
40 }
41
42 pub fn persistent(&self) -> ValueResult<PersistentHashSet> {
43 let set = self.set.lock().unwrap();
44 let mut persisted = self.persisted.lock().unwrap();
45 if *persisted {
46 return Err(ValueError::TransientAlreadyPersisted);
47 }
48 *persisted = true;
49 Ok(PersistentHashSet::from_set(set.clone()))
50 }
51
52 pub fn count(&self) -> usize {
53 let set = self.set.lock().unwrap();
54 set.size()
55 }
56}
57
58impl Clone for TransientSet {
59 fn clone(&self) -> Self {
60 Self {
61 set: Mutex::new(self.set.lock().unwrap().clone()),
62 persisted: Mutex::new(*self.persisted.lock().unwrap()),
63 }
64 }
65}
66
67impl ClojureHash for TransientSet {
68 fn clojure_hash(&self) -> u32 {
69 let mut hash: u32 = 0;
70 for v in self.set.lock().unwrap().iter() {
71 hash = hash_combine_unordered(hash, v.clojure_hash())
72 }
73 hash
74 }
75}
76
77impl cljrs_gc::Trace for TransientSet {
78 fn trace(&self, visitor: &mut cljrs_gc::MarkVisitor) {
79 {
80 let set = self.set.lock().unwrap();
81 for v in set.iter() {
82 v.trace(visitor);
83 }
84 }
85 }
86}
87
88impl Default for TransientSet {
89 fn default() -> Self {
90 Self::new()
91 }
92}