twasm_utils/
ref_list.rs

1#![warn(missing_docs)]
2
3use crate::std::rc::Rc;
4use crate::std::cell::RefCell;
5use crate::std::vec::Vec;
6use crate::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,
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,
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> crate::std::ops::Deref for Entry<T> {
54	type Target = T;
55
56	fn deref(&self) -> &T {
57		&self.val
58	}
59}
60
61impl<T> crate::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) -> crate::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) -> crate::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,
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 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 &mut entry.index {
205				EntryOrigin::Detached => unreachable!("Items in the list always have order!"),
206				EntryOrigin::Index(idx) => { *idx -= total_less; },
207			};
208		}
209
210		for (total_removed, idx) in indices.iter().enumerate() {
211			let detached = self.items.remove(*idx - total_removed);
212			detached.write().index = EntryOrigin::Detached;
213		}
214	}
215
216	fn done_insert(&mut self, index: usize, mut items: Vec<EntryRef<T>>) {
217		let mut offset = 0;
218		for item in items.drain(..) {
219			item.write().index = EntryOrigin::Index(index + offset);
220			self.items.insert(index + offset, item);
221			offset += 1;
222		}
223
224		for idx in (index+offset)..self.items.len() {
225			self.get_ref(idx).write().index = EntryOrigin::Index(idx);
226		}
227	}
228
229	/// Delete several items.
230	pub fn delete(&mut self, indices: &[usize]) {
231		self.done_delete(indices)
232	}
233
234	/// Delete one item.
235	pub fn delete_one(&mut self, index: usize) {
236		self.done_delete(&[index])
237	}
238
239	/// Initialize from slice.
240	///
241	/// Slice members are cloned.
242	pub fn from_slice(list: &[T]) -> Self
243		where T: Clone
244	{
245		let mut res = Self::new();
246
247		for t in list {
248			res.push(t.clone());
249		}
250
251		res
252	}
253
254	/// Length of the list.
255	pub fn len(&self) -> usize {
256		self.items.len()
257	}
258
259	/// Returns true iff len == 0.
260	pub fn is_empty(&self) -> bool {
261		self.len() == 0
262	}
263
264	/// Clone entry (reference counting object to item) by index.
265	///
266	/// Will panic if index out of bounds.
267	pub fn clone_ref(&self, idx: usize) -> EntryRef<T> {
268		self.items[idx].clone()
269	}
270
271	/// Get reference to entry by index.
272	///
273	/// Will panic if index out of bounds.
274	pub fn get_ref(&self, idx: usize) -> &EntryRef<T> {
275		&self.items[idx]
276	}
277
278	/// Iterate through entries.
279	pub fn iter(&self) -> slice::Iter<EntryRef<T>> {
280		self.items.iter()
281	}
282}
283
284/// Delete transaction.
285#[must_use]
286pub struct DeleteTransaction<'a, T> {
287	list: &'a mut RefList<T>,
288	deleted: Vec<usize>,
289}
290
291impl<'a, T> DeleteTransaction<'a, T> {
292	/// Add new element to the delete list.
293	pub fn push(self, idx: usize) -> Self {
294		let mut tx = self;
295		tx.deleted.push(idx);
296		tx
297	}
298
299	/// Commit transaction.
300	pub fn done(self) {
301		let indices = self.deleted;
302		let list = self.list;
303		list.done_delete(&indices[..]);
304	}
305}
306
307/// Insert transaction
308#[must_use]
309pub struct InsertTransaction<'a, T> {
310	at: usize,
311	list: &'a mut RefList<T>,
312	items: Vec<EntryRef<T>>,
313}
314
315impl<'a, T> InsertTransaction<'a, T> {
316	/// Add new element to the delete list.
317	pub fn push(&mut self, val: T) -> EntryRef<T> {
318		let val: EntryRef<_> = Entry::new_detached(val).into();
319		self.items.push(val.clone());
320		val
321	}
322
323	/// Commit transaction.
324	pub fn done(self) {
325		let items = self.items;
326		let list = self.list;
327		let at = self.at;
328		list.done_insert(at, items);
329	}
330}
331
332
333#[cfg(test)]
334mod tests {
335
336	use super::*;
337
338	#[test]
339	fn order() {
340		let mut list = RefList::<u32>::new();
341		let item00 = list.push(0);
342		let item10 = list.push(10);
343		let item20 = list.push(20);
344		let item30 = list.push(30);
345
346		assert_eq!(item00.order(), Some(0));
347		assert_eq!(item10.order(), Some(1));
348		assert_eq!(item20.order(), Some(2));
349		assert_eq!(item30.order(), Some(3));
350
351		assert_eq!(**item00.read(), 0);
352		assert_eq!(**item10.read(), 10);
353		assert_eq!(**item20.read(), 20);
354		assert_eq!(**item30.read(), 30);
355	}
356
357	#[test]
358	fn delete() {
359		let mut list = RefList::<u32>::new();
360		let item00 = list.push(0);
361		let item10 = list.push(10);
362		let item20 = list.push(20);
363		let item30 = list.push(30);
364
365		list.begin_delete().push(2).done();
366
367		assert_eq!(item00.order(), Some(0));
368		assert_eq!(item10.order(), Some(1));
369		assert_eq!(item30.order(), Some(2));
370
371		// but this was detached
372		assert_eq!(item20.order(), None);
373	}
374
375	#[test]
376	fn complex_delete() {
377		let mut list = RefList::<u32>::new();
378		let item00 = list.push(0);
379		let item10 = list.push(10);
380		let item20 = list.push(20);
381		let item30 = list.push(30);
382		let item40 = list.push(40);
383		let item50 = list.push(50);
384		let item60 = list.push(60);
385		let item70 = list.push(70);
386		let item80 = list.push(80);
387		let item90 = list.push(90);
388
389		list.begin_delete().push(1).push(2).push(4).push(6).done();
390
391		assert_eq!(item00.order(), Some(0));
392		assert_eq!(item10.order(), None);
393		assert_eq!(item20.order(), None);
394		assert_eq!(item30.order(), Some(1));
395		assert_eq!(item40.order(), None);
396		assert_eq!(item50.order(), Some(2));
397		assert_eq!(item60.order(), None);
398		assert_eq!(item70.order(), Some(3));
399		assert_eq!(item80.order(), Some(4));
400		assert_eq!(item90.order(), Some(5));
401	}
402
403	#[test]
404	fn insert() {
405		let mut list = RefList::<u32>::new();
406		let item00 = list.push(0);
407		let item10 = list.push(10);
408		let item20 = list.push(20);
409		let item30 = list.push(30);
410
411		let mut insert_tx = list.begin_insert(3);
412		let item23 = insert_tx.push(23);
413		let item27 = insert_tx.push(27);
414		insert_tx.done();
415
416		assert_eq!(item00.order(), Some(0));
417		assert_eq!(item10.order(), Some(1));
418		assert_eq!(item20.order(), Some(2));
419		assert_eq!(item23.order(), Some(3));
420		assert_eq!(item27.order(), Some(4));
421		assert_eq!(item30.order(), Some(5));
422	}
423
424	#[test]
425	fn insert_end() {
426		let mut list = RefList::<u32>::new();
427
428		let mut insert_tx = list.begin_insert(0);
429		let item0 = insert_tx.push(0);
430		insert_tx.done();
431
432		assert_eq!(item0.order(), Some(0));
433	}
434
435	#[test]
436	fn insert_end_more() {
437		let mut list = RefList::<u32>::new();
438		let item0 = list.push(0);
439
440		let mut insert_tx = list.begin_insert(1);
441		let item1 = insert_tx.push(1);
442		insert_tx.done();
443
444		assert_eq!(item0.order(), Some(0));
445		assert_eq!(item1.order(), Some(1));
446	}
447
448	#[test]
449	fn insert_after() {
450		let mut list = RefList::<u32>::new();
451		let item00 = list.push(0);
452		let item10 = list.push(10);
453		let item20 = list.push(20);
454		let item30 = list.push(30);
455
456		let mut insert_tx = list.begin_insert_after(|i| *i == 20);
457
458		let item23 = insert_tx.push(23);
459		let item27 = insert_tx.push(27);
460		insert_tx.done();
461
462		assert_eq!(item00.order(), Some(0));
463		assert_eq!(item10.order(), Some(1));
464		assert_eq!(item20.order(), Some(2));
465		assert_eq!(item23.order(), Some(3));
466		assert_eq!(item27.order(), Some(4));
467		assert_eq!(item30.order(), Some(5));
468	}
469
470	#[test]
471	fn insert_not_until() {
472		let mut list = RefList::<u32>::new();
473		let item10 = list.push(10);
474		let item20 = list.push(20);
475		let item30 = list.push(30);
476
477		let mut insert_tx = list.begin_insert_not_until(|i| *i <= 20);
478
479		let item23 = insert_tx.push(23);
480		let item27 = insert_tx.push(27);
481		insert_tx.done();
482
483		assert_eq!(item10.order(), Some(0));
484		assert_eq!(item20.order(), Some(1));
485		assert_eq!(item23.order(), Some(2));
486		assert_eq!(item27.order(), Some(3));
487		assert_eq!(item30.order(), Some(4));
488	}
489
490	#[test]
491	fn insert_after_none() {
492		let mut list = RefList::<u32>::new();
493		let item10 = list.push(10);
494		let item20 = list.push(20);
495		let item30 = list.push(30);
496
497		let mut insert_tx = list.begin_insert_after(|i| *i == 50);
498
499		let item55 = insert_tx.push(23);
500		let item59 = insert_tx.push(27);
501		insert_tx.done();
502
503		assert_eq!(item10.order(), Some(0));
504		assert_eq!(item20.order(), Some(1));
505		assert_eq!(item30.order(), Some(2));
506		assert_eq!(item55.order(), Some(3));
507		assert_eq!(item59.order(), Some(4));
508	}
509
510	#[test]
511	fn insert_not_until_none() {
512		let mut list = RefList::<u32>::new();
513		let item10 = list.push(10);
514		let item20 = list.push(20);
515		let item30 = list.push(30);
516
517		let mut insert_tx = list.begin_insert_not_until(|i| *i < 50);
518
519		let item55 = insert_tx.push(23);
520		let item59 = insert_tx.push(27);
521		insert_tx.done();
522
523		assert_eq!(item10.order(), Some(0));
524		assert_eq!(item20.order(), Some(1));
525		assert_eq!(item30.order(), Some(2));
526		assert_eq!(item55.order(), Some(3));
527		assert_eq!(item59.order(), Some(4));
528	}
529
530	#[test]
531	fn insert_after_empty() {
532		let mut list = RefList::<u32>::new();
533
534		let mut insert_tx = list.begin_insert_after(|x| *x == 100);
535		let item0 = insert_tx.push(0);
536		insert_tx.done();
537
538		assert_eq!(item0.order(), Some(0));
539	}
540
541	#[test]
542	fn insert_more() {
543		let mut list = RefList::<u32>::new();
544		let item10 = list.push(10);
545		let item20 = list.push(20);
546		let item30 = list.push(30);
547		let item40 = list.push(10);
548		let item50 = list.push(20);
549		let item60 = list.push(30);
550
551		let mut insert_tx = list.begin_insert(3);
552		let item35 = insert_tx.push(23);
553		let item37 = insert_tx.push(27);
554		insert_tx.done();
555
556		assert_eq!(item10.order(), Some(0));
557		assert_eq!(item20.order(), Some(1));
558		assert_eq!(item30.order(), Some(2));
559		assert_eq!(item35.order(), Some(3));
560		assert_eq!(item37.order(), Some(4));
561		assert_eq!(item40.order(), Some(5));
562		assert_eq!(item50.order(), Some(6));
563		assert_eq!(item60.order(), Some(7));
564	}
565}