xwasm_utils/
ref_list.rs

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