wasm_graph/
ref_list.rs

1
2use std::rc::Rc;
3use std::cell::RefCell;
4
5#[derive(Debug)]
6enum EntryOrigin {
7    Index(usize),
8    Detached,
9}
10
11impl From<usize> for EntryOrigin {
12    fn from(v: usize) -> Self {
13        EntryOrigin::Index(v)
14    }
15}
16
17/// Reference counting, link-handling object.
18#[derive(Debug)]
19pub struct Entry<T> {
20    val: T,
21    index: EntryOrigin,
22}
23
24impl<T> Entry<T> {
25    /// New entity.
26    pub fn new(val: T, index: usize) -> Entry<T> {
27        Entry {
28            val: val,
29            index: EntryOrigin::Index(index),
30        }
31    }
32
33    /// New detached entry.
34    pub fn new_detached(val: T) -> Entry<T> {
35        Entry {
36            val: val,
37            index: EntryOrigin::Detached,
38        }
39    }
40
41    /// Index of the element within the reference list.
42    pub fn order(&self) -> Option<usize> {
43        match self.index {
44            EntryOrigin::Detached => None,
45            EntryOrigin::Index(idx) => Some(idx),
46        }
47    }
48}
49
50impl<T> ::std::ops::Deref for Entry<T> {
51    type Target = T;
52
53    fn deref(&self) -> &T {
54        &self.val
55    }
56}
57
58impl<T> ::std::ops::DerefMut for Entry<T> {
59    fn deref_mut(&mut self) -> &mut T {
60        &mut self.val
61    }
62}
63
64/// Reference to the entry in the rerence list.
65#[derive(Debug)]
66pub struct EntryRef<T>(Rc<RefCell<Entry<T>>>);
67
68impl<T> Clone for EntryRef<T> {
69    fn clone(&self) -> Self {
70        EntryRef(self.0.clone())
71    }
72}
73
74impl<T> From<Entry<T>> for EntryRef<T> {
75    fn from(v: Entry<T>) -> Self {
76        EntryRef(Rc::new(RefCell::new(v)))
77    }
78}
79
80impl<T> EntryRef<T> {
81    /// Read the reference data.
82    pub fn read(&self) -> ::std::cell::Ref<Entry<T>> {
83        self.0.borrow()
84    }
85
86    /// Try to modify internal content of the referenced object.
87    ///
88    /// May panic if it is already borrowed.
89    pub fn write(&self) -> ::std::cell::RefMut<Entry<T>> {
90        self.0.borrow_mut()
91    }
92
93    /// Index of the element within the reference list.
94    pub fn order(&self) -> Option<usize> {
95        self.0.borrow().order()
96    }
97
98    /// Number of active links to this entity.
99    pub fn link_count(&self) -> usize {
100        Rc::strong_count(&self.0) - 1
101    }
102
103    /// If entry equals by ptr to another ref
104    pub fn eq(&self, other: &Self) -> bool {
105        Rc::ptr_eq(&self.0, &other.0)
106    }
107}
108
109/// List that tracks references and indices.
110#[derive(Debug)]
111pub struct RefList<T> {
112    items: Vec<EntryRef<T>>,
113}
114
115impl<T> Default for RefList<T> {
116    fn default() -> Self {
117        RefList { items: Default::default() }
118    }
119}
120
121impl<T> RefList<T> {
122
123    /// New empty list.
124    pub fn new() -> Self { Self::default() }
125
126    /// Push new element in the list.
127    ///
128    /// Returns refernce tracking entry.
129    pub fn push(&mut self, t: T) -> EntryRef<T> {
130        let idx = self.items.len();
131        let val: EntryRef<_> = Entry::new(t, idx).into();
132        self.items.push(val.clone());
133        val
134    }
135
136    /// Start deleting.
137    ///
138    /// Start deleting some entries in the list. Returns transaction
139    /// that can be populated with number of removed entries.
140    /// When transaction is finailized, all entries are deleted and
141    /// internal indices of other entries are updated.
142    pub fn begin_delete(&mut self) -> DeleteTransaction<T> {
143        DeleteTransaction {
144            list: self,
145            deleted: Vec::new(),
146        }
147    }
148
149    /// Start inserting.
150    ///
151    /// Start inserting some entries in the list at he designated position.
152    /// Returns transaction that can be populated with some entries.
153    /// When transaction is finailized, all entries are inserted and
154    /// internal indices of other entries might be updated.
155    pub fn begin_insert(&mut self, at: usize) -> InsertTransaction<T> {
156        InsertTransaction {
157            at: at,
158            list: self,
159            items: Vec::new(),
160        }
161    }
162
163    /// Start inserting after the condition first matches (or at the end).
164    ///
165    /// Start inserting some entries in the list at he designated position.
166    /// Returns transaction that can be populated with some entries.
167    /// When transaction is finailized, all entries are inserted and
168    /// internal indices of other entries might be updated.
169    pub fn begin_insert_after<F>(&mut self, mut f: F) -> InsertTransaction<T>
170        where F : FnMut(&T) -> bool
171    {
172        let pos = self
173            .items.iter()
174            .position(|rf| f(&**rf.read())).map(|x| x + 1)
175            .unwrap_or(self.items.len());
176
177        self.begin_insert(pos)
178    }
179
180    /// Start inserting after the condition first no longer true (or at the end).
181    ///
182    /// Start inserting some entries in the list at he designated position.
183    /// Returns transaction that can be populated with some entries.
184    /// When transaction is finailized, all entries are inserted and
185    /// internal indices of other entries might be updated.
186    pub fn begin_insert_not_until<F>(&mut self, mut f: F) -> InsertTransaction<T>
187        where F : FnMut(&T) -> bool
188    {
189        let pos = self.items.iter().take_while(|rf| f(&**rf.read())).count();
190        self.begin_insert(pos)
191    }
192
193    /// Get entry with index (checked).
194    ///
195    /// Can return None when index out of bounts.
196    pub fn get(&self, idx: usize) -> Option<EntryRef<T>> {
197        self.items.get(idx).cloned()
198    }
199
200    fn done_delete(&mut self, indices: &[usize]) {
201        for entry in self.items.iter_mut() {
202            let mut entry = entry.write();
203            let total_less = indices.iter()
204                .take_while(|x| **x < entry.order().expect("Items in the list always have order; qed"))
205                .count();
206            match entry.index {
207                EntryOrigin::Detached => unreachable!("Items in the list always have order!"),
208                EntryOrigin::Index(ref mut idx) => { *idx -= total_less; },
209            };
210        }
211
212        let mut total_removed = 0;
213        for idx in indices {
214            let detached = self.items.remove(*idx - total_removed);
215            detached.write().index = EntryOrigin::Detached;
216            total_removed += 1;
217        }
218    }
219
220    fn done_insert(&mut self, index: usize, mut items: Vec<EntryRef<T>>) {
221        let mut offset = 0;
222        for item in items.drain(..) {
223            item.write().index = EntryOrigin::Index(index + offset);
224            self.items.insert(index + offset, item);
225            offset += 1;
226        }
227
228        for idx in (index+offset)..self.items.len() {
229            self.get_ref(idx).write().index = EntryOrigin::Index(idx);
230        }
231    }
232
233    /// Delete several items.
234    pub fn delete(&mut self, indices: &[usize]) {
235        self.done_delete(indices)
236    }
237
238    /// Delete one item.
239    pub fn delete_one(&mut self, index: usize) {
240        self.done_delete(&[index])
241    }
242
243    /// Delete an entry (by ref)
244    pub fn delete_entry(&mut self, entry: &EntryRef<T>) -> bool {
245        if let Some((entry_index, _)) = self.items.iter().enumerate().find(|(_, item)| item.eq(entry)) {
246            self.delete_one(entry_index);
247            true
248        } else {
249            false
250        }
251    }
252
253    /// Initialize from slice.
254    ///
255    /// Slice members are cloned.
256    pub fn from_slice(list: &[T]) -> Self
257        where T: Clone
258    {
259        let mut res = Self::new();
260
261        for t in list {
262            res.push(t.clone());
263        }
264
265        res
266    }
267
268    /// Length of the list.
269    pub fn len(&self) -> usize {
270        self.items.len()
271    }
272
273    /// Clone entry (reference counting object to item) by index.
274    ///
275    /// Will panic if index out of bounds.
276    pub fn clone_ref(&self, idx: usize) -> EntryRef<T> {
277        self.items[idx].clone()
278    }
279
280    /// Get reference to entry by index.
281    ///
282    /// Will panic if index out of bounds.
283    pub fn get_ref(&self, idx: usize) -> &EntryRef<T> {
284        &self.items[idx]
285    }
286
287    /// Iterate through entries.
288    pub fn iter(&self) -> ::std::slice::Iter<EntryRef<T>> {
289        self.items.iter()
290    }
291}
292
293/// Delete transaction.
294#[must_use]
295pub struct DeleteTransaction<'a, T> {
296    list: &'a mut RefList<T>,
297    deleted: Vec<usize>,
298}
299
300impl<'a, T> DeleteTransaction<'a, T> {
301    /// Add new element to the delete list.
302    pub fn push(self, idx: usize) -> Self {
303        let mut tx = self;
304        tx.deleted.push(idx);
305        tx
306    }
307
308    /// Commit transaction.
309    pub fn done(self) {
310        let indices = self.deleted;
311        let list = self.list;
312        list.done_delete(&indices[..]);
313    }
314}
315
316/// Insert transaction
317#[must_use]
318pub struct InsertTransaction<'a, T> {
319    at: usize,
320    list: &'a mut RefList<T>,
321    items: Vec<EntryRef<T>>,
322}
323
324impl<'a, T> InsertTransaction<'a, T> {
325    /// Add new element to the delete list.
326    pub fn push(&mut self, val: T) -> EntryRef<T> {
327        let val: EntryRef<_> = Entry::new_detached(val).into();
328        self.items.push(val.clone());
329        val
330    }
331
332    /// Commit transaction.
333    pub fn done(self) {
334        let items = self.items;
335        let list = self.list;
336        let at = self.at;
337        list.done_insert(at, items);
338    }
339}
340
341
342#[cfg(test)]
343mod tests {
344
345    use super::*;
346
347    #[test]
348    fn order() {
349        let mut list = RefList::<u32>::new();
350        let item00 = list.push(0);
351        let item10 = list.push(10);
352        let item20 = list.push(20);
353        let item30 = list.push(30);
354
355        assert_eq!(item00.order(), Some(0));
356        assert_eq!(item10.order(), Some(1));
357        assert_eq!(item20.order(), Some(2));
358        assert_eq!(item30.order(), Some(3));
359
360        assert_eq!(**item00.read(), 0);
361        assert_eq!(**item10.read(), 10);
362        assert_eq!(**item20.read(), 20);
363        assert_eq!(**item30.read(), 30);
364    }
365
366    #[test]
367    fn delete() {
368        let mut list = RefList::<u32>::new();
369        let item00 = list.push(0);
370        let item10 = list.push(10);
371        let item20 = list.push(20);
372        let item30 = list.push(30);
373
374        list.begin_delete().push(2).done();
375
376        assert_eq!(item00.order(), Some(0));
377        assert_eq!(item10.order(), Some(1));
378        assert_eq!(item30.order(), Some(2));
379
380        // but this was detached
381        assert_eq!(item20.order(), None);
382    }
383
384    #[test]
385    fn complex_delete() {
386        let mut list = RefList::<u32>::new();
387        let item00 = list.push(0);
388        let item10 = list.push(10);
389        let item20 = list.push(20);
390        let item30 = list.push(30);
391        let item40 = list.push(40);
392        let item50 = list.push(50);
393        let item60 = list.push(60);
394        let item70 = list.push(70);
395        let item80 = list.push(80);
396        let item90 = list.push(90);
397
398        list.begin_delete().push(1).push(2).push(4).push(6).done();
399
400        assert_eq!(item00.order(), Some(0));
401        assert_eq!(item10.order(), None);
402        assert_eq!(item20.order(), None);
403        assert_eq!(item30.order(), Some(1));
404        assert_eq!(item40.order(), None);
405        assert_eq!(item50.order(), Some(2));
406        assert_eq!(item60.order(), None);
407        assert_eq!(item70.order(), Some(3));
408        assert_eq!(item80.order(), Some(4));
409        assert_eq!(item90.order(), Some(5));
410    }
411
412    #[test]
413    fn insert() {
414        let mut list = RefList::<u32>::new();
415        let item00 = list.push(0);
416        let item10 = list.push(10);
417        let item20 = list.push(20);
418        let item30 = list.push(30);
419
420        let mut insert_tx = list.begin_insert(3);
421        let item23 = insert_tx.push(23);
422        let item27 = insert_tx.push(27);
423        insert_tx.done();
424
425        assert_eq!(item00.order(), Some(0));
426        assert_eq!(item10.order(), Some(1));
427        assert_eq!(item20.order(), Some(2));
428        assert_eq!(item23.order(), Some(3));
429        assert_eq!(item27.order(), Some(4));
430        assert_eq!(item30.order(), Some(5));
431    }
432
433    #[test]
434    fn insert_end() {
435        let mut list = RefList::<u32>::new();
436
437        let mut insert_tx = list.begin_insert(0);
438        let item0 = insert_tx.push(0);
439        insert_tx.done();
440
441        assert_eq!(item0.order(), Some(0));
442    }
443
444    #[test]
445    fn insert_end_more() {
446        let mut list = RefList::<u32>::new();
447        let item0 = list.push(0);
448
449        let mut insert_tx = list.begin_insert(1);
450        let item1 = insert_tx.push(1);
451        insert_tx.done();
452
453        assert_eq!(item0.order(), Some(0));
454        assert_eq!(item1.order(), Some(1));
455    }
456
457    #[test]
458    fn insert_after() {
459        let mut list = RefList::<u32>::new();
460        let item00 = list.push(0);
461        let item10 = list.push(10);
462        let item20 = list.push(20);
463        let item30 = list.push(30);
464
465        let mut insert_tx = list.begin_insert_after(|i| *i == 20);
466
467        let item23 = insert_tx.push(23);
468        let item27 = insert_tx.push(27);
469        insert_tx.done();
470
471        assert_eq!(item00.order(), Some(0));
472        assert_eq!(item10.order(), Some(1));
473        assert_eq!(item20.order(), Some(2));
474        assert_eq!(item23.order(), Some(3));
475        assert_eq!(item27.order(), Some(4));
476        assert_eq!(item30.order(), Some(5));
477    }
478
479    #[test]
480    fn insert_not_until() {
481        let mut list = RefList::<u32>::new();
482        let item10 = list.push(10);
483        let item20 = list.push(20);
484        let item30 = list.push(30);
485
486        let mut insert_tx = list.begin_insert_not_until(|i| *i <= 20);
487
488        let item23 = insert_tx.push(23);
489        let item27 = insert_tx.push(27);
490        insert_tx.done();
491
492        assert_eq!(item10.order(), Some(0));
493        assert_eq!(item20.order(), Some(1));
494        assert_eq!(item23.order(), Some(2));
495        assert_eq!(item27.order(), Some(3));
496        assert_eq!(item30.order(), Some(4));
497    }
498
499    #[test]
500    fn insert_after_none() {
501        let mut list = RefList::<u32>::new();
502        let item10 = list.push(10);
503        let item20 = list.push(20);
504        let item30 = list.push(30);
505
506        let mut insert_tx = list.begin_insert_after(|i| *i == 50);
507
508        let item55 = insert_tx.push(23);
509        let item59 = insert_tx.push(27);
510        insert_tx.done();
511
512        assert_eq!(item10.order(), Some(0));
513        assert_eq!(item20.order(), Some(1));
514        assert_eq!(item30.order(), Some(2));
515        assert_eq!(item55.order(), Some(3));
516        assert_eq!(item59.order(), Some(4));
517    }
518
519    #[test]
520    fn insert_not_until_none() {
521        let mut list = RefList::<u32>::new();
522        let item10 = list.push(10);
523        let item20 = list.push(20);
524        let item30 = list.push(30);
525
526        let mut insert_tx = list.begin_insert_not_until(|i| *i < 50);
527
528        let item55 = insert_tx.push(23);
529        let item59 = insert_tx.push(27);
530        insert_tx.done();
531
532        assert_eq!(item10.order(), Some(0));
533        assert_eq!(item20.order(), Some(1));
534        assert_eq!(item30.order(), Some(2));
535        assert_eq!(item55.order(), Some(3));
536        assert_eq!(item59.order(), Some(4));
537    }
538
539    #[test]
540    fn insert_after_empty() {
541        let mut list = RefList::<u32>::new();
542
543        let mut insert_tx = list.begin_insert_after(|x| *x == 100);
544        let item0 = insert_tx.push(0);
545        insert_tx.done();
546
547        assert_eq!(item0.order(), Some(0));
548    }
549
550    #[test]
551    fn insert_more() {
552        let mut list = RefList::<u32>::new();
553        let item10 = list.push(10);
554        let item20 = list.push(20);
555        let item30 = list.push(30);
556        let item40 = list.push(10);
557        let item50 = list.push(20);
558        let item60 = list.push(30);
559
560        let mut insert_tx = list.begin_insert(3);
561        let item35 = insert_tx.push(23);
562        let item37 = insert_tx.push(27);
563        insert_tx.done();
564
565        assert_eq!(item10.order(), Some(0));
566        assert_eq!(item20.order(), Some(1));
567        assert_eq!(item30.order(), Some(2));
568        assert_eq!(item35.order(), Some(3));
569        assert_eq!(item37.order(), Some(4));
570        assert_eq!(item40.order(), Some(5));
571        assert_eq!(item50.order(), Some(6));
572        assert_eq!(item60.order(), Some(7));
573    }
574
575    #[test]
576    fn delete_by_ref() {
577        let mut list = RefList::<u32>::new();
578        let item10 = list.push(10);
579        let item20 = list.push(20);
580        let item30 = list.push(30);
581
582        let item_ref_2 = item20.clone();
583
584        list.delete_entry(&item_ref_2);
585        assert_eq!(item10.order(), Some(0));
586        assert_eq!(item20.order(), None);
587        assert_eq!(item30.order(), Some(1));
588    }
589}