1use std::cell::RefCell;
2use std::ptr::NonNull;
3
4thread_local! {
5 static CRGC: RefCell<CycleRemover> = RefCell::new(CycleRemover::init());
6 static TEMP: RefCell<Vec<usize>> = RefCell::new(Vec::new());
7}
8
9pub trait Trace: 'static {
10 fn step1(&self);
11 fn step2(&self);
12}
13pub(crate) trait Tracer {
14 fn count(&self) -> usize;
15 fn index(&self) -> usize;
16 fn run_step1(&mut self);
17 fn run_step2(&mut self);
18 unsafe fn free(&mut self);
19}
20
21pub struct CycleRemover {
22 pub(crate) list: Vec<Option<NonNull<dyn Tracer>>>,
23 pub(crate) stack: Vec<usize>,
24}
25impl CycleRemover {
26 #[inline]
27 fn init() -> CycleRemover {
28 CycleRemover {
29 list: Vec::new(),
30 stack: Vec::new(),
31 }
32 }
33}
34impl CycleRemover {
35 #[inline]
36 fn append(&mut self, meta: NonNull<dyn Tracer>) -> usize {
37 if let Some(i) = self.stack.pop() {
38 self.list[i] = Some(meta);
39 return i;
40 } else {
41 let i = self.list.len();
42 self.list.push(Some(meta));
43 return i;
44 }
45 }
46 #[inline]
47 fn remove(&mut self, i: usize) {
48 self.list[i] = None;
49 self.stack.push(i);
50 }
51}
52impl CycleRemover {
53 #[inline]
54 fn temp(i: usize) {
55 TEMP.with(|temp| temp.borrow_mut().push(i));
56 }
57 #[inline]
58 fn collect(&mut self) {
59 let iter = self.list.iter();
60 for i in iter {
61 if let Some(a) = i {
62 unsafe {
63 (*(*a).as_ptr()).run_step1();
64 }
65 }
66 }
67 TEMP.with(|tref| {
68 let mut temp = tref.borrow_mut();
69 temp.sort();
70
71 let mut titer = temp.iter();
72 let mut ti = titer.next();
73
74 let mut ci = 0;
75 let iter = self.list.iter();
76 for i in iter {
77 let step2 = || {
78 if let Some(a) = i {
79 unsafe {
80 (*(*a).as_ptr()).run_step2();
81 }
82 }
83 };
84 if let Some(x) = ti {
85 if *x != ci {
86 step2();
87 } else {
88 ti = titer.next();
89 }
90 } else {
91 step2();
92 }
93 ci += 1;
94 }
95
96 let iter = temp.iter();
97 for i in iter {
98 if let Some(x) = self.list[*i] {
99 unsafe {
100 if (*x.as_ptr()).count() == 0 {
101 self.remove((*x.as_ptr()).index());
102 (*x.as_ptr()).free();
103 }
104 }
105 }
106 }
107 temp.clear();
108 });
109 }
110}
111
112pub fn collect() {
113 CRGC.with(|crgc| crgc.borrow_mut().collect())
114}
115pub(crate) fn append(meta: NonNull<dyn Tracer>) -> usize {
116 CRGC.with(|crgc| crgc.borrow_mut().append(meta))
117}
118pub(crate) fn remove(i: usize) {
119 CRGC.with(|crgc| crgc.borrow_mut().remove(i));
120}
121pub(crate) fn temp(i: usize) {
122 CycleRemover::temp(i);
123}