object_space/
object_space.rs

1use std::any::TypeId;
2use std::ops::RangeBounds;
3use std::sync::{Arc, Condvar, Mutex};
4
5use chashmap::{CHashMap, ReadGuard, WriteGuard};
6use serde::{Deserialize, Serialize};
7use serde_json::value::{from_value, to_value};
8
9use entry::{Entry, RangeLookupEntry, ValueLookupEntry};
10use helpers::{deflatten, flatten};
11
12/// Basic interface of an ObjectSpace.
13///
14/// This trait includes pushing, reading, and popping structs from the space.
15/// An implementation of ObjectSpace should be thread-safe for usage in concurrent programs.
16///
17/// # Example
18///
19/// ```
20/// # use object_space::{TreeObjectSpace, ObjectSpace};
21/// let space = TreeObjectSpace::new();
22/// space.write(String::from("Hello World"));
23/// assert_eq!(
24///     space.try_read::<String>(),
25///     Some(String::from("Hello World"))
26/// );
27/// ```
28pub trait ObjectSpace {
29    /// Add a struct to the object space.
30    ///
31    /// # Example
32    ///
33    /// ```
34    /// # use object_space::{TreeObjectSpace, ObjectSpace};
35    /// let space = TreeObjectSpace::new();
36    /// space.write(String::from("Hello World"));
37    /// ```
38    fn write<T>(&self, obj: T)
39    where
40        for<'de> T: Serialize + Deserialize<'de> + 'static;
41
42    /// Return a copy of a struct of type T.
43    /// The operation is non-blocking
44    /// and will returns None if no struct satisfies condition.
45    ///
46    /// # Example
47    ///
48    /// ```
49    /// # use object_space::{TreeObjectSpace, ObjectSpace};
50    /// let space = TreeObjectSpace::new();
51    /// space.write(String::from("Hello World"));
52    /// assert_eq!(
53    ///     space.try_read::<String>(),
54    ///     Some(String::from("Hello World"))
55    /// );
56    /// ```
57    fn try_read<T>(&self) -> Option<T>
58    where
59        for<'de> T: Serialize + Deserialize<'de> + 'static;
60
61    /// Return copies of all structs of type T.
62    /// The operation is non-blocking and will returns None if no struct satisfies condition.
63    ///
64    /// # Example
65    ///
66    /// ```
67    /// # use object_space::{TreeObjectSpace, ObjectSpace};
68    /// let space = TreeObjectSpace::new();
69    /// assert_eq!(space.read_all::<String>().count(), 0);
70    /// space.write("Hello".to_string());
71    /// space.write("World".to_string());
72    ///
73    /// assert_eq!(
74    ///     space.read_all::<String>().collect::<Vec<String>>(),
75    ///     vec!["Hello", "World"]
76    /// );
77    /// ```
78    fn read_all<'a, T>(&'a self) -> Box<Iterator<Item = T> + 'a>
79    where
80        for<'de> T: Serialize + Deserialize<'de> + 'static;
81
82    /// Return a copy of a struct of type T.
83    /// The operation blocks until such a struct is found.
84    ///
85    /// # Example
86    ///
87    /// ```
88    /// # use object_space::{TreeObjectSpace, ObjectSpace};
89    /// let space = TreeObjectSpace::new();
90    /// space.write(String::from("Hello World"));
91    /// assert_eq!(
92    ///     space.read::<String>(),
93    ///     String::from("Hello World")
94    /// );
95    /// ```
96    fn read<T>(&self) -> T
97    where
98        for<'de> T: Serialize + Deserialize<'de> + 'static;
99
100    /// Remove and return a struct of type T.
101    /// The operation is non-blocking and will returns None if no struct satisfies condition.
102    ///
103    /// # Example
104    ///
105    /// ```
106    /// # use object_space::{TreeObjectSpace, ObjectSpace};
107    /// let space = TreeObjectSpace::new();
108    /// space.write(String::from("Hello World"));
109    /// assert_eq!(
110    ///     space.try_take::<String>(),
111    ///     Some(String::from("Hello World"))
112    /// );
113    /// assert_eq!(space.try_take::<String>(), None);
114    /// ```
115    fn try_take<T>(&self) -> Option<T>
116    where
117        for<'de> T: Serialize + Deserialize<'de> + 'static;
118
119    /// Remove and return all structs of type T.
120    /// The operation is non-blocking and will returns None if no struct satisfies condition.
121    ///
122    /// # Example
123    ///
124    /// ```
125    /// # use object_space::{TreeObjectSpace, ObjectSpace};
126    /// let space = TreeObjectSpace::new();
127    /// assert_eq!(space.take_all::<String>().count(), 0);
128    /// space.write("Hello".to_string());
129    /// space.write("World".to_string());
130    ///
131    /// assert_eq!(
132    ///     space.take_all::<String>().collect::<Vec<String>>(),
133    ///     vec!["Hello", "World"]
134    /// );
135    /// assert_eq!(space.take_all::<String>().count(), 0);
136    /// ```
137    fn take_all<'a, T>(&'a self) -> Box<Iterator<Item = T> + 'a>
138    where
139        for<'de> T: Serialize + Deserialize<'de> + 'static;
140
141    /// Remove and return a struct of type T.
142    /// The operation blocks until such a struct is found.
143    /// # Example
144    ///
145    /// ```
146    /// # use object_space::{TreeObjectSpace, ObjectSpace};
147    /// let space = TreeObjectSpace::new();
148    /// space.write(String::from("Hello World"));
149    /// assert_eq!(
150    ///     space.take::<String>(),
151    ///     String::from("Hello World")
152    /// );
153    /// assert_eq!(space.try_take::<String>(), None);
154    /// ```
155    fn take<T>(&self) -> T
156    where
157        for<'de> T: Serialize + Deserialize<'de> + 'static;
158}
159
160/// An extension of `ObjectSpace` supporting retrieving structs by range of a field.
161///
162/// Given a type `T` with a field (might be nested) of type `U`,
163/// a path to a field of type `U` and a `RangeBounds<U>`,
164/// an `RangeLookupObjectSpace<U>` could retrieve structs of type `T`
165/// whose value of the specified field is within the given range.
166///
167/// # Example
168///
169/// ```
170/// # use object_space::{TreeObjectSpace, ObjectSpace, RangeLookupObjectSpace};
171/// let space = TreeObjectSpace::new();
172/// space.write::<i64>(3);
173/// space.write::<i64>(5);
174///
175/// assert_eq!(space.try_read_by_range::<i64, _>("", 2..4), Some(3));
176/// assert_eq!(space.try_read_by_range::<i64, _>("", ..2), None);
177/// ```
178pub trait RangeLookupObjectSpace<U>: ObjectSpace {
179    /// Given a path to an element of the struct and a range of possible values,
180    /// return a copy of a struct whose specified element is within the range.
181    /// The operation is non-blocking and will returns None if no struct satisfies condition.
182    ///
183    /// # Example
184    ///
185    /// ```
186    /// # use object_space::{TreeObjectSpace, ObjectSpace, RangeLookupObjectSpace};
187    /// let space = TreeObjectSpace::new();
188    /// space.write::<i64>(3);
189    /// space.write::<i64>(5);
190    ///
191    /// assert_eq!(space.try_read_by_range::<i64, _>("", 2..4), Some(3));
192    /// assert_eq!(space.try_read_by_range::<i64, _>("", ..2), None);
193    /// ```
194    fn try_read_by_range<T, R>(&self, field: &str, range: R) -> Option<T>
195    where
196        for<'de> T: Serialize + Deserialize<'de> + 'static,
197        R: RangeBounds<U> + Clone;
198
199    /// Given a path to an element of the struct and a range of possible values,
200    /// return copies of all structs whose specified element is within the range.
201    ///
202    /// # Example
203    ///
204    /// ```
205    /// # use object_space::{TreeObjectSpace, ObjectSpace, RangeLookupObjectSpace};
206    /// let space = TreeObjectSpace::new();
207    /// space.write::<i64>(3);
208    /// space.write::<i64>(5);
209    ///
210    /// assert_eq!(space.read_all_by_range::<i64, _>("", 2..4).count(), 1);
211    /// assert_eq!(space.read_all_by_range::<i64, _>("", 2..).count(), 2);
212    /// ```
213    fn read_all_by_range<'a, T, R>(&'a self, field: &str, range: R) -> Box<Iterator<Item = T> + 'a>
214    where
215        for<'de> T: Deserialize<'de> + 'static,
216        R: RangeBounds<U> + Clone;
217
218    /// Given a path to an element of the struct and a range of possible values,
219    /// return a copy of a struct whose specified element is within the range.
220    /// The operation blocks until a struct satisfies the condition is found.
221    ///
222    /// # Example
223    ///
224    /// ```
225    /// # use object_space::{TreeObjectSpace, ObjectSpace, RangeLookupObjectSpace};
226    /// let space = TreeObjectSpace::new();
227    /// space.write::<i64>(3);
228    /// space.write::<i64>(5);
229    ///
230    /// assert_eq!(space.read_by_range::<i64, _>("", 2..4), 3);
231    /// ```
232    fn read_by_range<T, R>(&self, field: &str, range: R) -> T
233    where
234        for<'de> T: Serialize + Deserialize<'de> + 'static,
235        R: RangeBounds<U> + Clone;
236
237    /// Given a path to an element of the struct and a range of possible values,
238    /// remove and return a struct whose specified element is within the range.
239    /// The operation is non-blocking and will returns None if no struct satisfies condition.
240    ///
241    /// # Example
242    ///
243    /// ```
244    /// # use object_space::{TreeObjectSpace, ObjectSpace, RangeLookupObjectSpace};
245    /// let space = TreeObjectSpace::new();
246    /// space.write::<i64>(3);
247    /// space.write::<i64>(5);
248    ///
249    /// assert_eq!(space.try_take_by_range::<i64, _>("", 2..4), Some(3));
250    /// assert_eq!(space.try_take_by_range::<i64, _>("", 2..4), None);
251    /// assert_eq!(space.try_take_by_range::<i64, _>("", 2..), Some(5));
252    /// ```
253    fn try_take_by_range<T, R>(&self, field: &str, range: R) -> Option<T>
254    where
255        for<'de> T: Serialize + Deserialize<'de> + 'static,
256        R: RangeBounds<U> + Clone;
257
258    /// Given a path to an element of the struct and a range of possible values,
259    /// remove and return all structs whose specified element is within the range.
260    ///
261    /// # Example
262    ///
263    /// ```
264    /// # use object_space::{TreeObjectSpace, ObjectSpace, RangeLookupObjectSpace};
265    /// let space = TreeObjectSpace::new();
266    /// space.write::<i64>(3);
267    /// space.write::<i64>(5);
268    ///
269    /// assert_eq!(space.take_all_by_range::<i64, _>("", 2..4).count(), 1);
270    /// assert_eq!(space.take_all_by_range::<i64, _>("", 2..).count(), 1);
271    /// ```
272    fn take_all_by_range<'a, T, R>(&'a self, field: &str, range: R) -> Box<Iterator<Item = T> + 'a>
273    where
274        for<'de> T: Deserialize<'de> + 'static,
275        R: RangeBounds<U> + Clone;
276
277    /// Given a path to an element of the struct and a range of possible values,
278    /// remove and return a struct whose specified element is within the range.
279    /// The operation blocks until a struct satisfies the condition is found.
280    ///
281    /// # Example
282    ///
283    /// ```
284    /// # use object_space::{TreeObjectSpace, ObjectSpace, RangeLookupObjectSpace};
285    /// let space = TreeObjectSpace::new();
286    /// space.write::<i64>(3);
287    /// space.write::<i64>(5);
288    ///
289    /// assert_eq!(space.take_by_range::<i64, _>("", 2..4), 3);
290    /// assert_eq!(space.take_by_range::<i64, _>("", 2..), 5);
291    /// ```
292    fn take_by_range<T, R>(&self, field: &str, range: R) -> T
293    where
294        for<'de> T: Serialize + Deserialize<'de> + 'static,
295        R: RangeBounds<U> + Clone;
296}
297
298/// An extension of `ObjectSpace` supporting retrieving structs by value of a field.
299///
300/// Given a type `T` with a field (might be nested) of type `U`,
301/// a path to a field of type `U` and a value of type `U`,
302/// an `ValueLookupObjectSpace<U>` could retrieve structs of type `T`
303/// whose value of the specified field equals to the specified value.
304///
305/// # Example
306///
307/// ```
308/// # use object_space::{TreeObjectSpace, ObjectSpace, ValueLookupObjectSpace};
309/// let space = TreeObjectSpace::new();
310/// space.write::<i64>(3);
311/// space.write::<i64>(5);
312///
313/// assert_eq!(space.try_read_by_value::<i64>("", &3), Some(3));
314/// assert_eq!(space.try_read_by_value::<i64>("", &2), None);
315/// ```
316pub trait ValueLookupObjectSpace<U>: ObjectSpace {
317    /// Given a path to an element of the struct and a possible value,
318    /// return a copy of a struct whose specified element of the specified value.
319    /// The operation is non-blocking and will returns None if no struct satisfies condition.
320    ///
321    /// # Example
322    ///
323    /// ```
324    /// # use object_space::{TreeObjectSpace, ObjectSpace, ValueLookupObjectSpace};
325    /// let space = TreeObjectSpace::new();
326    /// space.write::<i64>(3);
327    /// space.write::<i64>(5);
328    ///
329    /// assert_eq!(space.try_read_by_value::<i64>("", &3), Some(3));
330    /// assert_eq!(space.try_read_by_value::<i64>("", &2), None);
331    /// ```
332    fn try_read_by_value<T>(&self, field: &str, key: &U) -> Option<T>
333    where
334        for<'de> T: Serialize + Deserialize<'de> + 'static;
335
336    /// Given a path to an element of the struct and a possible value,
337    /// return copies of all structs whose specified element of the specified value.
338    ///
339    /// # Example
340    ///
341    /// ```
342    /// # use object_space::{TreeObjectSpace, ObjectSpace, ValueLookupObjectSpace};
343    /// let space = TreeObjectSpace::new();
344    /// space.write::<i64>(3);
345    /// space.write::<i64>(5);
346    ///
347    /// assert_eq!(space.read_all_by_value::<i64>("", &3).count(), 1);
348    /// assert_eq!(space.read_all_by_value::<i64>("", &2).count(), 0);
349    /// ```
350    fn read_all_by_value<'a, T>(&'a self, field: &str, key: &U) -> Box<Iterator<Item = T> + 'a>
351    where
352        for<'de> T: Deserialize<'de> + 'static;
353
354    /// Given a path to an element of the struct and a possible value,
355    /// return a copy of a struct whose specified element of the specified value.
356    /// The operation is blocks until an element satisfies the condition is found.
357    ///
358    /// # Example
359    ///
360    /// ```
361    /// # use object_space::{TreeObjectSpace, ObjectSpace, ValueLookupObjectSpace};
362    /// let space = TreeObjectSpace::new();
363    /// space.write::<i64>(3);
364    /// space.write::<i64>(5);
365    ///
366    /// assert_eq!(space.read_by_value::<i64>("", &3), 3);
367    /// ```
368    fn read_by_value<T>(&self, field: &str, key: &U) -> T
369    where
370        for<'de> T: Serialize + Deserialize<'de> + 'static;
371
372    /// Given a path to an element of the struct and a possible value,
373    /// remove and return a struct whose specified element of the specified value.
374    /// The operation is non-blocking and will returns None if no struct satisfies condition.
375    ///
376    /// # Example
377    ///
378    /// ```
379    /// # use object_space::{TreeObjectSpace, ObjectSpace, ValueLookupObjectSpace};
380    /// let space = TreeObjectSpace::new();
381    /// space.write::<i64>(3);
382    /// space.write::<i64>(5);
383    ///
384    /// assert_eq!(space.try_take_by_value::<i64>("", &3), Some(3));
385    /// assert_eq!(space.try_take_by_value::<i64>("", &3), None);
386    /// assert_eq!(space.try_take_by_value::<i64>("", &4), None);
387    /// ```
388    fn try_take_by_value<T>(&self, field: &str, key: &U) -> Option<T>
389    where
390        for<'de> T: Serialize + Deserialize<'de> + 'static;
391
392    /// Given a path to an element of the struct and a possible value,
393    /// remove and return all structs whose specified element of the specified value.
394    ///
395    /// # Example
396    ///
397    /// ```
398    /// # use object_space::{TreeObjectSpace, ObjectSpace, ValueLookupObjectSpace};
399    /// let space = TreeObjectSpace::new();
400    /// space.write::<i64>(3);
401    /// space.write::<i64>(5);
402    ///
403    /// assert_eq!(space.take_all_by_value::<i64>("", &3).count(), 1);
404    /// assert_eq!(space.take_all_by_value::<i64>("", &4).count(), 0);
405    /// ```
406    fn take_all_by_value<'a, T>(&'a self, field: &str, key: &U) -> Box<Iterator<Item = T> + 'a>
407    where
408        for<'de> T: Deserialize<'de> + 'static;
409
410    /// Given a path to an element of the struct and a possible value,
411    /// remove and return a struct whose specified element of the specified value.
412    /// The operation is blocks until an element satisfies the condition is found.
413    ///
414    /// # Example
415    ///
416    /// ```
417    /// # use object_space::{TreeObjectSpace, ObjectSpace, ValueLookupObjectSpace};
418    /// let space = TreeObjectSpace::new();
419    /// space.write::<i64>(3);
420    /// space.write::<i64>(5);
421    ///
422    /// assert_eq!(space.take_by_value::<i64>("", &3), 3);
423    /// ```
424    fn take_by_value<T>(&self, field: &str, key: &U) -> T
425    where
426        for<'de> T: Serialize + Deserialize<'de> + 'static;
427}
428
429type Lock = Arc<(Mutex<bool>, Condvar)>;
430
431/// A thread-safe reference `ObjectSpace` implementation
432///
433/// # Implementation
434///
435/// A `TreeObjectSpace` is a `HashMap` between a `TypeId`
436/// and the actual `Entry` structure holding the structs.
437/// Before structs are stored in `Entry`,
438/// they are serialized into a JSON-like structure and then flattened.
439///
440/// An `Entry` is a `HashMap` whose key is a flattened field and
441/// value is a `BTreeMap` between possible values of the field
442/// and the `Vec` of structs containing the corresponding value of such field.
443///
444/// `Mutex` is used sparingly to ensure blocking `read` and `take` calls do not hijack CPU cycles
445#[derive(Default)]
446pub struct TreeObjectSpace {
447    typeid_entries_dict: CHashMap<TypeId, Entry>,
448    lock_dict: CHashMap<TypeId, Lock>,
449}
450
451impl TreeObjectSpace {
452    pub fn new() -> TreeObjectSpace {
453        Default::default()
454    }
455
456    fn get_object_entry_ref<T>(&self) -> Option<ReadGuard<TypeId, Entry>>
457    where
458        T: 'static,
459    {
460        let type_id = TypeId::of::<T>();
461        self.typeid_entries_dict.get(&type_id)
462    }
463
464    fn get_object_entry_mut<T>(&self) -> Option<WriteGuard<TypeId, Entry>>
465    where
466        T: 'static,
467    {
468        let type_id = TypeId::of::<T>();
469        self.typeid_entries_dict.get_mut(&type_id)
470    }
471
472    fn get_lock<T>(&self) -> Option<ReadGuard<TypeId, Lock>>
473    where
474        T: 'static,
475    {
476        let type_id = TypeId::of::<T>();
477        self.lock_dict.get(&type_id)
478    }
479
480    fn add_entry(&self, id: TypeId) {
481        let default_value = Entry::new();
482
483        self.typeid_entries_dict
484            .upsert(id, || default_value, |_| ());
485        self.lock_dict
486            .upsert(id, || Arc::new((Mutex::new(false), Condvar::new())), |_| ());
487    }
488}
489
490impl ObjectSpace for TreeObjectSpace {
491    fn write<T>(&self, obj: T)
492    where
493        for<'de> T: Serialize + Deserialize<'de> + 'static,
494    {
495        let type_id = TypeId::of::<T>();
496        self.add_entry(type_id);
497        let &(ref lock, ref cvar) = &*self.get_lock::<T>().unwrap().clone();
498        let value = flatten(to_value(obj).expect("struct cannot be serialized"));
499        let mut status = lock.lock().unwrap();
500        *status = !*status;
501        self.typeid_entries_dict
502            .get_mut(&type_id)
503            .unwrap()
504            .add(value);
505        cvar.notify_all();
506    }
507
508    fn try_read<T>(&self) -> Option<T>
509    where
510        for<'de> T: Serialize + Deserialize<'de> + 'static,
511    {
512        let value = match self.get_object_entry_ref::<T>() {
513            Some(entry) => entry.get(),
514            _ => None,
515        };
516        match value {
517            Some(val) => from_value(deflatten(val)).ok(),
518            _ => None,
519        }
520    }
521
522    fn read_all<'a, T>(&'a self) -> Box<Iterator<Item = T> + 'a>
523    where
524        for<'de> T: Serialize + Deserialize<'de> + 'static,
525    {
526        let val_iter: Vec<_> = match self.get_object_entry_ref::<T>() {
527            Some(ent) => ent.get_all().collect(),
528            None => Vec::new(),
529        };
530
531        Box::new(
532            val_iter
533                .into_iter()
534                .filter_map(|item| from_value(deflatten(item)).ok()),
535        )
536    }
537
538    fn read<T>(&self) -> T
539    where
540        for<'de> T: Serialize + Deserialize<'de> + 'static,
541    {
542        self.add_entry(TypeId::of::<T>());
543        let &(ref lock, ref cvar) = &*self.get_lock::<T>().unwrap().clone();
544        let value;
545        {
546            let mut fetched = lock.lock().unwrap();
547            loop {
548                let result = match self.get_object_entry_ref::<T>() {
549                    Some(entry) => entry.get(),
550                    _ => None,
551                };
552                if let Some(item) = result {
553                    value = item;
554                    break;
555                }
556                fetched = cvar.wait(fetched).unwrap();
557            }
558        }
559        from_value(deflatten(value)).unwrap()
560    }
561
562    fn try_take<T>(&self) -> Option<T>
563    where
564        for<'de> T: Serialize + Deserialize<'de> + 'static,
565    {
566        let value = match self.get_object_entry_mut::<T>() {
567            Some(mut entry) => entry.remove(),
568            _ => None,
569        };
570        match value {
571            Some(val) => from_value(deflatten(val)).ok(),
572            _ => None,
573        }
574    }
575
576    fn take_all<'a, T>(&'a self) -> Box<Iterator<Item = T> + 'a>
577    where
578        for<'de> T: Serialize + Deserialize<'de> + 'static,
579    {
580        let val_iter = match self.get_object_entry_mut::<T>() {
581            Some(mut ent) => ent.remove_all(),
582            None => Vec::new(),
583        };
584
585        Box::new(
586            val_iter
587                .into_iter()
588                .filter_map(|item| from_value(deflatten(item)).ok()),
589        )
590    }
591
592    fn take<T>(&self) -> T
593    where
594        for<'de> T: Serialize + Deserialize<'de> + 'static,
595    {
596        self.add_entry(TypeId::of::<T>());
597        let &(ref lock, ref cvar) = &*self.get_lock::<T>().unwrap().clone();
598        let value;
599        {
600            let mut fetched = lock.lock().unwrap();
601            loop {
602                let result = match self.get_object_entry_mut::<T>() {
603                    Some(mut entry) => entry.remove(),
604                    _ => None,
605                };
606                if let Some(item) = result {
607                    value = item;
608                    break;
609                }
610                fetched = cvar.wait(fetched).unwrap();
611            }
612        }
613        from_value(deflatten(value)).unwrap()
614    }
615}
616
617macro_rules! object_range{
618    ($($ty:ident)*) => {
619        $(
620            impl RangeLookupObjectSpace<$ty> for TreeObjectSpace {
621                fn try_read_by_range<T, R>(&self, field: &str, range: R) -> Option<T>
622                where
623                    for<'de> T: Serialize + Deserialize<'de> + 'static,
624                    R: RangeBounds<$ty> + Clone,
625                {
626                    let value = match self.get_object_entry_ref::<T>() {
627                        Some(entry) => entry.get_by_range::<_>(field, range),
628                        _ => None,
629                    };
630                    match value {
631                        Some(val) => from_value(deflatten(val)).ok(),
632                        _ => None,
633                    }
634                }
635
636                fn read_all_by_range<'a, T, R>(&'a self, field: &str, range: R) -> Box<Iterator<Item = T> + 'a>
637                where
638                    for<'de> T: Deserialize<'de> + 'static,
639                    R: RangeBounds<$ty> + Clone,
640                {
641                    let val_iter: Vec<_> = match self.get_object_entry_ref::<T>() {
642                        Some(ent) => ent.get_all_by_range::<_>(field, range).collect(),
643                        None => Vec::new(),
644                    };
645
646                    Box::new(val_iter.into_iter().filter_map(|item| from_value(deflatten(item)).ok()))
647                }
648
649                fn read_by_range<T, R>(&self, field: &str, range: R) -> T
650                where
651                    for<'de> T: Serialize + Deserialize<'de> + 'static,
652                    R: RangeBounds<$ty> + Clone,
653                {
654                    self.add_entry(TypeId::of::<T>());
655                    let &(ref lock, ref cvar) = &*self.get_lock::<T>().unwrap().clone();
656                    let value;
657                    {
658                        let mut fetched = lock.lock().unwrap();
659                        loop {
660                            let result = match self.get_object_entry_ref::<T>() {
661                                Some(entry) => entry.get_by_range::<_>(field, range.clone()),
662                                _ => None,
663                            };
664                            if let Some(item) = result {
665                                value = item;
666                                break;
667                            }
668                            fetched = cvar.wait(fetched).unwrap();
669                        }
670                    }
671                    from_value(deflatten(value)).unwrap()
672                }
673
674                fn try_take_by_range<T, R>(&self, field: &str, range: R) -> Option<T>
675                where
676                    for<'de> T: Serialize + Deserialize<'de> + 'static,
677                    R: RangeBounds<$ty> + Clone,
678                {
679                    let value = match self.get_object_entry_mut::<T>() {
680                        Some(mut entry) => entry.remove_by_range::<_>(field, range),
681                        _ => None,
682                    };
683                    match value {
684                        Some(val) => from_value(deflatten(val)).ok(),
685                        _ => None,
686                    }
687                }
688
689                fn take_all_by_range<'a, T, R>(
690                    &'a self,
691                    field: &str,
692                    range: R,
693                ) -> Box<Iterator<Item = T> + 'a>
694                where
695                    for<'de> T: Deserialize<'de> + 'static,
696                    R: RangeBounds<$ty> + Clone,
697                {
698                    let val_iter = match self.get_object_entry_mut::<T>() {
699                        Some(mut ent) => ent.remove_all_by_range::<_>(field, range),
700                        None => Vec::new(),
701                    };
702
703                    Box::new(
704                        val_iter
705                            .into_iter()
706                            .filter_map(|item| from_value(deflatten(item)).ok())
707                    )
708                }
709
710                fn take_by_range<T, R>(&self, field: &str, range: R) -> T
711                where
712                    for<'de> T: Serialize + Deserialize<'de> + 'static,
713                    R: RangeBounds<$ty> + Clone,
714                {
715                    self.add_entry(TypeId::of::<T>());
716                    let &(ref lock, ref cvar) = &*self.get_lock::<T>().unwrap().clone();
717                    let value;
718                    {
719                        let mut fetched = lock.lock().unwrap();
720                        loop {
721                            let result = match self.get_object_entry_mut::<T>() {
722                                Some(mut entry) => entry.remove_by_range::<_>(field, range.clone()),
723                                _ => None,
724                            };
725                            if let Some(item) = result {
726                                value = item;
727                                break;
728                            }
729                            fetched = cvar.wait(fetched).unwrap();
730                        }
731                    }
732                    from_value(deflatten(value)).unwrap()
733                }
734            }
735        )*
736    };
737}
738
739macro_rules! object_key{
740    ($($ty:ty)*) => {
741        $(
742            impl ValueLookupObjectSpace<$ty> for TreeObjectSpace {
743                fn try_read_by_value<T>(&self, field: &str, key: &$ty) -> Option<T>
744                where
745                    for<'de> T: Serialize + Deserialize<'de> + 'static,
746                {
747                    let value = match self.get_object_entry_ref::<T>() {
748                        Some(entry) => entry.get_by_value(field, key),
749                        _ => None,
750                    };
751                    match value {
752                        Some(val) => from_value(deflatten(val)).ok(),
753                        _ => None,
754                    }
755                }
756
757                fn read_all_by_value<'a, T>(&'a self, field: &str, key: &$ty) -> Box<Iterator<Item = T> + 'a>
758                where
759                    for<'de> T: Deserialize<'de> + 'static,
760                {
761                    let val_iter: Vec<_> = match self.get_object_entry_ref::<T>() {
762                        Some(ent) => ent.get_all_by_value(field, key).collect(),
763                        None => Vec::new(),
764                    };
765
766                    Box::new(val_iter.into_iter().filter_map(|item| from_value(deflatten(item)).ok()))
767                }
768
769                fn read_by_value<T>(&self, field: &str, key: &$ty) -> T
770                where
771                    for<'de> T: Serialize + Deserialize<'de> + 'static,
772                {
773                    self.add_entry(TypeId::of::<T>());
774                    let &(ref lock, ref cvar) = &*self.get_lock::<T>().unwrap().clone();
775                    let value;
776                    {
777                        let mut fetched = lock.lock().unwrap();
778                        loop {
779                            let result = match self.get_object_entry_ref::<T>() {
780                                Some(entry) => entry.get_by_value(field, key),
781                                _ => None,
782                            };
783                            if let Some(item) = result {
784                                value = item;
785                                break;
786                            }
787                            fetched = cvar.wait(fetched).unwrap();
788                        }
789                    }
790                    from_value(deflatten(value)).unwrap()
791                }
792
793                fn try_take_by_value<T>(&self, field: &str, key: &$ty) -> Option<T>
794                where
795                    for<'de> T: Serialize + Deserialize<'de> + 'static,
796                {
797                    let value = match self.get_object_entry_mut::<T>() {
798                        Some(mut entry) => entry.remove_by_value(field, key),
799                        _ => None,
800                    };
801                    match value {
802                        Some(val) => from_value(deflatten(val)).ok(),
803                        _ => None,
804                    }
805                }
806
807                fn take_all_by_value<'a, T>(
808                    &'a self,
809                    field: &str,
810                    key: &$ty,
811                ) -> Box<Iterator<Item = T> + 'a>
812                where
813                    for<'de> T: Deserialize<'de> + 'static,
814                {
815                    let val_iter = match self.get_object_entry_mut::<T>() {
816                        Some(mut ent) => ent.remove_all_by_value(field, key),
817                        None => Vec::new(),
818                    };
819
820                    Box::new(
821                        val_iter
822                            .into_iter()
823                            .filter_map(|item| from_value(deflatten(item)).ok())
824                    )
825                }
826
827                fn take_by_value<T>(&self, field: &str, key: &$ty) -> T
828                where
829                    for<'de> T: Serialize + Deserialize<'de> + 'static,
830                {
831                    self.add_entry(TypeId::of::<T>());
832                    let &(ref lock, ref cvar) = &*self.get_lock::<T>().unwrap().clone();
833                    let value;
834                    {
835                        let mut fetched = lock.lock().unwrap();
836                        loop {
837                            let result = match self.get_object_entry_mut::<T>() {
838                                Some(mut entry) => entry.remove_by_value(field, key),
839                                _ => None,
840                            };
841                            if let Some(item) = result {
842                                value = item;
843                                break;
844                            }
845                            fetched = cvar.wait(fetched).unwrap();
846                        }
847                    }
848                    from_value(deflatten(value)).unwrap()
849                }
850            }
851        )*
852    };
853}
854
855object_range!{i64 String f64}
856object_key!{i64 String bool f64}
857
858mod tests {
859    use super::*;
860
861    #[derive(Serialize, Deserialize, PartialEq, Debug)]
862    struct TestStruct {
863        count: i32,
864        name: String,
865    }
866
867    #[derive(Serialize, Deserialize, PartialEq, Debug)]
868    struct CompoundStruct {
869        person: TestStruct,
870        gpa: f64,
871    }
872
873    #[derive(Serialize, Deserialize, PartialEq, Debug)]
874    enum TestEnum {
875        String(String),
876        Int(i32),
877        Struct { count: i32, name: String },
878    }
879
880    #[test]
881    fn try_read() {
882        let space = TreeObjectSpace::new();
883        assert_eq!(space.try_read::<String>(), None);
884        space.write(String::from("Hello World"));
885        space.write(TestStruct {
886            count: 3,
887            name: String::from("Tuan"),
888        });
889        space.write(CompoundStruct {
890            person: TestStruct {
891                count: 3,
892                name: String::from("Tuan"),
893            },
894            gpa: 3.0,
895        });
896
897        assert_eq!(
898            space.try_read::<String>(),
899            Some(String::from("Hello World"))
900        );
901        assert_ne!(space.try_read::<String>(), None);
902
903        assert_eq!(
904            space.try_read::<TestStruct>(),
905            Some(TestStruct {
906                count: 3,
907                name: String::from("Tuan"),
908            })
909        );
910
911        assert_eq!(
912            space.try_read::<CompoundStruct>(),
913            Some(CompoundStruct {
914                person: TestStruct {
915                    count: 3,
916                    name: String::from("Tuan"),
917                },
918                gpa: 3.0
919            })
920        );
921        assert!(space.try_read::<CompoundStruct>().is_some());
922    }
923
924    #[test]
925    fn try_take() {
926        let space = TreeObjectSpace::new();
927        assert_eq!(space.try_take::<String>(), None);
928        space.write(String::from("Hello World"));
929        space.write(TestStruct {
930            count: 3,
931            name: String::from("Tuan"),
932        });
933        space.write(CompoundStruct {
934            person: TestStruct {
935                count: 3,
936                name: String::from("Tuan"),
937            },
938            gpa: 3.5,
939        });
940
941        assert_eq!(
942            space.try_take::<String>(),
943            Some(String::from("Hello World"))
944        );
945        assert_eq!(space.try_take::<String>(), None);
946
947        assert_eq!(
948            space.try_take::<TestStruct>(),
949            Some(TestStruct {
950                count: 3,
951                name: String::from("Tuan"),
952            })
953        );
954        assert_eq!(space.try_take::<TestStruct>(), None);
955
956        assert_eq!(
957            space.try_take::<CompoundStruct>(),
958            Some(CompoundStruct {
959                person: TestStruct {
960                    count: 3,
961                    name: String::from("Tuan"),
962                },
963                gpa: 3.5
964            })
965        );
966        assert!(space.try_take::<CompoundStruct>().is_none());
967    }
968
969    #[test]
970    fn read_all() {
971        let space = TreeObjectSpace::new();
972        assert_eq!(space.read_all::<String>().count(), 0);
973        space.write("Hello".to_string());
974        space.write("World".to_string());
975        space.write(TestStruct {
976            count: 3,
977            name: String::from("Tuan"),
978        });
979        space.write(TestStruct {
980            count: 5,
981            name: String::from("Duane"),
982        });
983
984        assert_eq!(
985            space.read_all::<String>().collect::<Vec<String>>(),
986            vec!["Hello", "World"]
987        );
988        assert_ne!(space.read_all::<String>().count(), 0);
989
990        assert_eq!(space.read_all::<TestStruct>().count(), 2);
991        assert_eq!(space.read_all::<TestStruct>().count(), 2);
992    }
993
994    #[test]
995    fn take_all() {
996        let space = TreeObjectSpace::new();
997        assert_eq!(space.take_all::<String>().count(), 0);
998        space.write("Hello".to_string());
999        space.write("World".to_string());
1000        space.write(TestStruct {
1001            count: 3,
1002            name: String::from("Tuan"),
1003        });
1004        space.write(TestStruct {
1005            count: 5,
1006            name: String::from("Duane"),
1007        });
1008
1009        assert_eq!(space.take_all::<String>().count(), 2);
1010        assert_eq!(space.take_all::<String>().count(), 0);
1011
1012        assert_eq!(space.take_all::<TestStruct>().count(), 2);
1013        assert_eq!(space.take_all::<TestStruct>().count(), 0);
1014    }
1015
1016    #[test]
1017    fn try_read_by_range() {
1018        let space = TreeObjectSpace::new();
1019        assert_eq!(space.try_read_by_range::<i64, _>("", 2..4), None);
1020        space.write::<i64>(3);
1021        space.write::<i64>(5);
1022
1023        assert_eq!(space.try_read_by_range::<i64, _>("", 2..4), Some(3));
1024        assert_ne!(space.try_read_by_range::<i64, _>("", 2..4), None);
1025
1026        space.write(TestStruct {
1027            count: 3,
1028            name: String::from("Tuan"),
1029        });
1030        space.write(TestStruct {
1031            count: 5,
1032            name: String::from("Duane"),
1033        });
1034
1035        assert_eq!(
1036            space.try_read_by_range::<TestStruct, _>("count", 2..4),
1037            Some(TestStruct {
1038                count: 3,
1039                name: String::from("Tuan"),
1040            })
1041        );
1042        assert!(
1043            space
1044                .try_read_by_range::<TestStruct, _>("count", 2..4)
1045                .is_some()
1046        );
1047
1048        space.write(CompoundStruct {
1049            person: TestStruct {
1050                count: 5,
1051                name: String::from("Duane"),
1052            },
1053            gpa: 3.0,
1054        });
1055        space.write(CompoundStruct {
1056            person: TestStruct {
1057                count: 3,
1058                name: String::from("Tuan"),
1059            },
1060            gpa: 3.5,
1061        });
1062
1063        assert_eq!(
1064            space.try_read_by_range::<CompoundStruct, _>("person.count", 2..4),
1065            Some(CompoundStruct {
1066                person: TestStruct {
1067                    count: 3,
1068                    name: String::from("Tuan"),
1069                },
1070                gpa: 3.5
1071            })
1072        );
1073        assert!(
1074            space
1075                .try_read_by_range::<CompoundStruct, _>("person.count", 2..4)
1076                .is_some()
1077        );
1078    }
1079
1080    #[test]
1081    fn try_take_by_range() {
1082        let space = TreeObjectSpace::new();
1083        assert_eq!(space.try_take_by_range::<i64, _>("", 2..4), None);
1084        space.write::<i64>(3);
1085        space.write::<i64>(5);
1086        assert_eq!(space.try_take_by_range::<i64, _>("", 2..4), Some(3));
1087        assert_eq!(space.try_take_by_range::<i64, _>("", 2..4), None);
1088
1089        space.write(TestStruct {
1090            count: 3,
1091            name: String::from("Tuan"),
1092        });
1093        space.write(TestStruct {
1094            count: 5,
1095            name: String::from("Duane"),
1096        });
1097
1098        assert_eq!(
1099            space.try_take_by_range::<TestStruct, _>("count", 2..4),
1100            Some(TestStruct {
1101                count: 3,
1102                name: String::from("Tuan"),
1103            })
1104        );
1105        assert!(
1106            space
1107                .try_take_by_range::<TestStruct, _>("count", 2..4)
1108                .is_none()
1109        );
1110
1111        space.write(CompoundStruct {
1112            person: TestStruct {
1113                count: 3,
1114                name: String::from("Tuan"),
1115            },
1116            gpa: 3.0,
1117        });
1118        space.write(CompoundStruct {
1119            person: TestStruct {
1120                count: 5,
1121                name: String::from("Duane"),
1122            },
1123            gpa: 3.5,
1124        });
1125
1126        assert_eq!(
1127            space.try_take_by_range::<CompoundStruct, _>("gpa", 3.0..3.5),
1128            Some(CompoundStruct {
1129                person: TestStruct {
1130                    count: 3,
1131                    name: String::from("Tuan"),
1132                },
1133                gpa: 3.0
1134            })
1135        );
1136        assert!(
1137            space
1138                .try_take_by_range::<CompoundStruct, _>("person.count", 2..4)
1139                .is_none()
1140        );
1141    }
1142
1143    #[test]
1144    fn read_all_by_range() {
1145        let space = TreeObjectSpace::new();
1146        space.write::<i64>(3);
1147        space.write::<i64>(5);
1148        assert_eq!(space.read_all_by_range::<i64, _>("", 2..4).count(), 1);
1149        assert_eq!(space.read_all_by_range::<i64, _>("", 2..4).count(), 1);
1150
1151        space.write(TestStruct {
1152            count: 3,
1153            name: String::from("Tuan"),
1154        });
1155        space.write(TestStruct {
1156            count: 3,
1157            name: String::from("Minh"),
1158        });
1159
1160        space.write(TestStruct {
1161            count: 5,
1162            name: String::from("Duane"),
1163        });
1164
1165        assert_eq!(
1166            space
1167                .read_all_by_range::<TestStruct, _>("count", 2..4)
1168                .count(),
1169            2
1170        );
1171        assert_eq!(
1172            space
1173                .read_all_by_range::<TestStruct, _>("count", 2..4)
1174                .count(),
1175            2
1176        );
1177
1178        space.write(CompoundStruct {
1179            person: TestStruct {
1180                count: 5,
1181                name: String::from("Duane"),
1182            },
1183            gpa: 4.0,
1184        });
1185        space.write(CompoundStruct {
1186            person: TestStruct {
1187                count: 3,
1188                name: String::from("Tuan"),
1189            },
1190            gpa: 3.0,
1191        });
1192        space.write(CompoundStruct {
1193            person: TestStruct {
1194                count: 3,
1195                name: String::from("Minh"),
1196            },
1197            gpa: 3.0,
1198        });
1199
1200        assert_eq!(
1201            space
1202                .read_all_by_range::<CompoundStruct, _>("gpa", 2.5..4.0)
1203                .count(),
1204            2
1205        );
1206        assert_eq!(
1207            space
1208                .read_all_by_range::<CompoundStruct, _>("person.count", 2..4)
1209                .count(),
1210            2
1211        );
1212    }
1213
1214    #[test]
1215    fn take_all_by_range() {
1216        let space = TreeObjectSpace::new();
1217        space.write::<i64>(3);
1218        space.write::<i64>(5);
1219        assert_eq!(space.take_all_by_range::<i64, _>("", 2..4).count(), 1);
1220        assert_eq!(space.take_all_by_range::<i64, _>("", 2..4).count(), 0);
1221
1222        space.write(TestStruct {
1223            count: 3,
1224            name: String::from("Tuan"),
1225        });
1226        space.write(TestStruct {
1227            count: 3,
1228            name: String::from("Minh"),
1229        });
1230
1231        space.write(TestStruct {
1232            count: 5,
1233            name: String::from("Duane"),
1234        });
1235
1236        assert_eq!(
1237            space
1238                .take_all_by_range::<TestStruct, _>("count", 2..4)
1239                .count(),
1240            2
1241        );
1242        assert_eq!(
1243            space
1244                .take_all_by_range::<TestStruct, _>("count", 2..4)
1245                .count(),
1246            0
1247        );
1248        assert_eq!(
1249            space
1250                .take_all_by_range::<TestStruct, _>("count", 4..)
1251                .count(),
1252            1
1253        );
1254
1255        space.write(CompoundStruct {
1256            person: TestStruct {
1257                count: 5,
1258                name: String::from("Duane"),
1259            },
1260            gpa: 3.5,
1261        });
1262        space.write(CompoundStruct {
1263            person: TestStruct {
1264                count: 3,
1265                name: String::from("Tuan"),
1266            },
1267            gpa: 3.0,
1268        });
1269        space.write(CompoundStruct {
1270            person: TestStruct {
1271                count: 3,
1272                name: String::from("Minh"),
1273            },
1274            gpa: 3.0,
1275        });
1276
1277        assert_eq!(
1278            space
1279                .take_all_by_range::<CompoundStruct, _>("gpa", 2.5..3.5)
1280                .count(),
1281            2
1282        );
1283        assert_eq!(
1284            space
1285                .take_all_by_range::<CompoundStruct, _>("person.count", 2..4)
1286                .count(),
1287            0
1288        );
1289        assert_eq!(
1290            space
1291                .take_all_by_range::<CompoundStruct, _>("gpa", 3.5..)
1292                .count(),
1293            1
1294        );
1295    }
1296
1297    #[test]
1298    fn try_read_by_value() {
1299        let space = TreeObjectSpace::new();
1300        assert_eq!(space.try_read_by_value::<i64>("", &3), None);
1301        space.write::<i64>(3);
1302        space.write::<i64>(5);
1303
1304        assert_eq!(space.try_read_by_value::<i64>("", &3), Some(3));
1305        assert_eq!(space.try_read_by_value::<i64>("", &2), None);
1306
1307        space.write(TestStruct {
1308            count: 3,
1309            name: String::from("Tuan"),
1310        });
1311        space.write(TestStruct {
1312            count: 5,
1313            name: String::from("Duane"),
1314        });
1315
1316        assert_eq!(
1317            space.try_read_by_value::<TestStruct>("count", &3),
1318            Some(TestStruct {
1319                count: 3,
1320                name: String::from("Tuan"),
1321            })
1322        );
1323        assert!(space.try_read_by_value::<TestStruct>("count", &3).is_some());
1324
1325        space.write(CompoundStruct {
1326            person: TestStruct {
1327                count: 5,
1328                name: String::from("Duane"),
1329            },
1330            gpa: 4.0,
1331        });
1332        space.write(CompoundStruct {
1333            person: TestStruct {
1334                count: 3,
1335                name: String::from("Tuan"),
1336            },
1337            gpa: 3.0,
1338        });
1339
1340        assert_eq!(
1341            space.try_read_by_value::<CompoundStruct>("person.count", &3),
1342            Some(CompoundStruct {
1343                person: TestStruct {
1344                    count: 3,
1345                    name: String::from("Tuan"),
1346                },
1347                gpa: 3.0
1348            })
1349        );
1350        assert!(
1351            space
1352                .try_read_by_value::<CompoundStruct>("gpa", &3.0)
1353                .is_some()
1354        );
1355    }
1356
1357    #[test]
1358    fn try_take_by_value() {
1359        let space = TreeObjectSpace::new();
1360        assert_eq!(space.try_take_by_value::<i64>("", &3), None);
1361        space.write::<i64>(3);
1362        space.write::<i64>(5);
1363        assert_eq!(space.try_take_by_value::<i64>("", &4), None);
1364        assert_eq!(space.try_take_by_value::<i64>("", &3), Some(3));
1365        assert_eq!(space.try_take_by_value::<i64>("", &3), None);
1366
1367        space.write(TestStruct {
1368            count: 3,
1369            name: String::from("Tuan"),
1370        });
1371        assert_eq!(
1372            space.try_take_by_value::<TestStruct>("count", &3),
1373            Some(TestStruct {
1374                count: 3,
1375                name: String::from("Tuan"),
1376            })
1377        );
1378        assert!(space.try_take_by_value::<TestStruct>("count", &3).is_none());
1379
1380        space.write(CompoundStruct {
1381            person: TestStruct {
1382                count: 3,
1383                name: String::from("Tuan"),
1384            },
1385            gpa: 3.0,
1386        });
1387
1388        assert_eq!(
1389            space.try_take_by_value::<CompoundStruct>("person.count", &3),
1390            Some(CompoundStruct {
1391                person: TestStruct {
1392                    count: 3,
1393                    name: String::from("Tuan"),
1394                },
1395                gpa: 3.0
1396            })
1397        );
1398        assert!(
1399            space
1400                .try_take_by_value::<CompoundStruct>("gpa", &3.0)
1401                .is_none()
1402        );
1403    }
1404
1405    #[test]
1406    fn read_all_by_value() {
1407        let space = TreeObjectSpace::new();
1408        space.write::<i64>(3);
1409        space.write::<i64>(5);
1410        assert_eq!(space.read_all_by_value::<i64>("", &3).count(), 1);
1411        assert_eq!(space.read_all_by_value::<i64>("", &4).count(), 0);
1412
1413        space.write(TestStruct {
1414            count: 3,
1415            name: String::from("Tuan"),
1416        });
1417        space.write(TestStruct {
1418            count: 3,
1419            name: String::from("Minh"),
1420        });
1421
1422        space.write(TestStruct {
1423            count: 5,
1424            name: String::from("Duane"),
1425        });
1426
1427        assert_eq!(
1428            space.read_all_by_value::<TestStruct>("count", &3).count(),
1429            2
1430        );
1431        assert_eq!(
1432            space.read_all_by_value::<TestStruct>("count", &4).count(),
1433            0
1434        );
1435
1436        space.write(CompoundStruct {
1437            person: TestStruct {
1438                count: 5,
1439                name: String::from("Duane"),
1440            },
1441            gpa: 4.0,
1442        });
1443        space.write(CompoundStruct {
1444            person: TestStruct {
1445                count: 3,
1446                name: String::from("Tuan"),
1447            },
1448            gpa: 3.0,
1449        });
1450        space.write(CompoundStruct {
1451            person: TestStruct {
1452                count: 3,
1453                name: String::from("Minh"),
1454            },
1455            gpa: 3.5,
1456        });
1457
1458        assert_eq!(
1459            space
1460                .read_all_by_value::<CompoundStruct>("person.count", &3)
1461                .count(),
1462            2
1463        );
1464        assert_eq!(
1465            space
1466                .read_all_by_value::<CompoundStruct>("person.count", &4)
1467                .count(),
1468            0
1469        );
1470        assert_eq!(
1471            space
1472                .read_all_by_value::<CompoundStruct>("gpa", &4.0)
1473                .count(),
1474            1
1475        );
1476    }
1477
1478    #[test]
1479    fn take_all_by_value() {
1480        let space = TreeObjectSpace::new();
1481        space.write::<i64>(3);
1482        space.write::<i64>(5);
1483        assert_eq!(space.take_all_by_value::<i64>("", &3).count(), 1);
1484        assert_eq!(space.take_all_by_value::<i64>("", &4).count(), 0);
1485
1486        space.write(TestStruct {
1487            count: 3,
1488            name: String::from("Tuan"),
1489        });
1490        space.write(TestStruct {
1491            count: 3,
1492            name: String::from("Minh"),
1493        });
1494
1495        space.write(TestStruct {
1496            count: 5,
1497            name: String::from("Duane"),
1498        });
1499
1500        assert_eq!(
1501            space.take_all_by_value::<TestStruct>("count", &3).count(),
1502            2
1503        );
1504        assert_eq!(
1505            space.take_all_by_value::<TestStruct>("count", &3).count(),
1506            0
1507        );
1508        assert_eq!(
1509            space.take_all_by_value::<TestStruct>("count", &5).count(),
1510            1
1511        );
1512
1513        space.write(CompoundStruct {
1514            person: TestStruct {
1515                count: 5,
1516                name: String::from("Duane"),
1517            },
1518            gpa: 4.0,
1519        });
1520        space.write(CompoundStruct {
1521            person: TestStruct {
1522                count: 3,
1523                name: String::from("Tuan"),
1524            },
1525            gpa: 3.0,
1526        });
1527        space.write(CompoundStruct {
1528            person: TestStruct {
1529                count: 3,
1530                name: String::from("Minh"),
1531            },
1532            gpa: 3.0,
1533        });
1534
1535        assert_eq!(
1536            space
1537                .take_all_by_value::<CompoundStruct>("gpa", &3.0)
1538                .count(),
1539            2
1540        );
1541        assert_eq!(
1542            space
1543                .take_all_by_value::<CompoundStruct>("person.count", &3)
1544                .count(),
1545            0
1546        );
1547        assert_eq!(
1548            space
1549                .take_all_by_value::<CompoundStruct>("person.count", &5)
1550                .count(),
1551            1
1552        );
1553    }
1554
1555    #[test]
1556    fn read_enum_range() {
1557        let space = TreeObjectSpace::new();
1558        assert_eq!(space.read_all::<TestEnum>().count(), 0);
1559        space.write(TestEnum::Int(4));
1560        assert_eq!(space.read::<TestEnum>(), TestEnum::Int(4));
1561        assert_eq!(
1562            space.try_read_by_value::<TestEnum>("Int", &4),
1563            Some(TestEnum::Int(4))
1564        );
1565        assert_eq!(
1566            space.try_read_by_value::<TestEnum>("Struct.count", &4),
1567            None
1568        );
1569        assert_eq!(
1570            space.try_read_by_range::<TestEnum, _>("Struct.count", 3..5),
1571            None
1572        );
1573
1574        space.write(TestEnum::Struct {
1575            count: 4,
1576            name: String::from("Tuan"),
1577        });
1578        assert_eq!(
1579            space.read_by_value::<TestEnum>("Struct.count", &4),
1580            TestEnum::Struct {
1581                count: 4,
1582                name: String::from("Tuan")
1583            }
1584        );
1585        assert_eq!(
1586            space.take_by_range::<TestEnum, _>("Struct.count", 3..5),
1587            TestEnum::Struct {
1588                count: 4,
1589                name: String::from("Tuan")
1590            }
1591        );
1592        assert_eq!(space.read::<TestEnum>(), TestEnum::Int(4));
1593    }
1594}