1use std::ops::{Index, IndexMut};
2use eta_algorithms::data_structs::array::Array;
3use eta_algorithms::data_structs::fat_ptr::{FatPtr, FatPtrMut};
4use crate::handles::{pack, vh};
5use crate::handles::types::{VHandle, Weight, Edge, Ci};
6use crate::traits::{EdgeManipulate, EdgeConnect, EdgeStore, WeightedEdgeManipulate, WeightedEdgeConnect};
7#[derive(Copy, Clone)]
8pub struct VertexEntry {
9 pub len: Ci,
10 pub capacity: Ci,
11 pub offset: Ci,
12}
13
14pub struct EdgeStorageIter<'a> {
15 edges: &'a Array<Edge>,
16 current: *const Edge,
17 end: *const Edge,
18 entries_iter: core::slice::Iter<'a, VertexEntry>,
19}
20impl<'a> EdgeStorageIter<'a> {
21 pub fn new(edge_storage: &'a EdgeStorage) -> Self {
22 let mut entries_iter = edge_storage.vertex_entries.iter();
23 let next = entries_iter.next().unwrap();
24 let current = unsafe { edge_storage.edges.as_ptr().add(next.offset as usize) };
25 let end = unsafe { current.add(next.len as usize) };
26 EdgeStorageIter {
27 edges: &edge_storage.edges,
28 current,
29 end,
30 entries_iter,
31 }
32 }
33}
34
35macro_rules! edge_storage_iter_impl {
36 ($impl_name:ident $(,$mut_type:ident)?) => {
37 impl<'a> Iterator for $impl_name<'a> {
38 type Item = &'a $($mut_type)? Edge;
39 fn next(&mut self) -> Option<Self::Item> {
40 while self.current == self.end {
41 let result = self.entries_iter.next();
42 result?;
43
44 let next = result.unwrap();
45 edge_storage_iter_impl!(@get_current self, next $($mut_type)?);
46
47 self.end = unsafe { self.current.add(next.len as usize) };
48 }
49 let result = edge_storage_iter_impl!(@get_result self, next $($mut_type)?);
50 self.current = unsafe { self.current.add(1) };
51 result
52 }
53 }
54 };
55
56 (@get_result $self:ident ,$next:ident) => {
57 unsafe{Some($self.current.as_ref().unwrap())}
58 };
59
60 (@get_result $self:ident ,$next:ident mut) => {
61 unsafe{Some($self.current.as_mut().unwrap())}
62 };
63
64 (@get_current $self:ident ,$next:ident) => {
65 $self.current = unsafe { $self.edges.as_ptr().add($next.offset as usize) };
66 };
67 (@get_current $self:ident ,$next:ident mut) => {
68 $self.current = unsafe { $self.edges.as_mut_ptr().add($next.offset as usize) };
69 };
70}
71edge_storage_iter_impl!(EdgeStorageIter);
72pub struct EdgeStorageIterMut<'a> {
73 edges: &'a mut Array<Edge>,
74 current: *mut Edge,
75 end: *mut Edge,
76 entries_iter: core::slice::Iter<'a, VertexEntry>,
77}
78impl<'a> EdgeStorageIterMut<'a> {
79 pub fn new(edge_storage: & 'a mut EdgeStorage) -> Self {
80 let mut entries_iter = edge_storage.vertex_entries.iter();
81 let next = entries_iter.next().unwrap();
82 let current = unsafe { edge_storage.edges.as_mut_ptr().add(next.offset as usize) };
83 let end = unsafe { current.add(next.len as usize) };
84 EdgeStorageIterMut {
85 edges: &mut edge_storage.edges,
86 current,
87 end,
88 entries_iter,
89 }
90 }
91}
92edge_storage_iter_impl!(EdgeStorageIterMut, mut);
93
94pub struct EdgeStorage {
95 pub(in crate) reserve: Ci,
96 pub edges: Array<Edge>,
97 vertex_entries: Vec<VertexEntry>,
98}
99
100impl Default for EdgeStorage {
101 #[inline(always)]
102 fn default() -> Self {
103 Self::new()
104 }
105}
106
107impl EdgeStorage {
108 pub fn new_large() -> Self {
111 EdgeStorage {
112 reserve: 50,
113 edges: Array::new(0),
114 vertex_entries: Vec::new(),
115 }
116 }
117 pub fn with_reserve(capacity: Ci) -> Self {
119 EdgeStorage {
120 reserve: capacity,
121 edges: Array::new(0),
122 vertex_entries: Vec::new(),
123 }
124 }
125
126 pub fn new() -> Self {
128 EdgeStorage {
129 reserve: 0,
130 edges: Array::new(0),
131 vertex_entries: Vec::new(),
132 }
133 }
134}
135
136impl EdgeConnect for EdgeStorage {
137 fn connect_edges(&mut self, from: VHandle, to: &[Edge]) {
138 let len = self.edges_len(from);
139 let new_size = len + to.len();
140
141 if new_size > self.edges_capacity(from) {
142 panic!("Edge size is greater than the allocated size");
143 }
144
145 let data = self.edges_as_mut_slice(from);
146 data[len..new_size].copy_from_slice(to);
147 self.vertex_entries[from as usize].len = new_size as Ci;
148 }
149
150 fn disconnect(&mut self, from: VHandle, to: VHandle) {
151 let data = self.edges_as_mut_ptr(from);
152 let len = &mut self.vertex_entries[from as usize].len;
153 unsafe {
154 for edge in data {
155 if vh(*edge) == to {
156 *edge = *data.end.offset(-1); *len -= 1;
158 break;
159 }
160 }
161 }
162 }
163 #[inline(always)]
164 fn connect(&mut self, from: VHandle, to: VHandle) {
165 self.connect_edges(from, &[pack(to, 0)]);
166 }
167}
168
169impl WeightedEdgeConnect for EdgeStorage {
170 fn connect_weighted(&mut self, from: VHandle, to: VHandle, weight: Weight) {
171 self.connect_edges(from, &[pack(to, weight)]);
172 }
173}
174impl EdgeStore for EdgeStorage {
175 fn create_vertex_entry(&mut self, size: Ci) -> VHandle {
176 let offset = self.edges.capacity() as Ci;
177 self.edges.extend_by((size + self.reserve) as usize);
178 self.vertex_entries.push(VertexEntry {
179 len: 0,
180 capacity: self.reserve + size,
181 offset,
182 });
183 (self.vertex_entries.len() - 1) as VHandle
184 }
185 #[inline(always)]
186 fn edges_as_slice(&self, vertex: VHandle) -> &[Edge] {
187 let edge_chunk_meta = self.vertex_entries[vertex as usize];
188 &self.edges.as_slice()[edge_chunk_meta.offset as usize..(edge_chunk_meta.offset + edge_chunk_meta.len) as usize]
189 }
190 #[inline(always)]
191 fn edges_as_mut_slice(&mut self, vertex: VHandle) -> &mut [Edge] {
192 let edge_chunk_meta = self.vertex_entries[vertex as usize];
193 &mut self.edges.as_mut_slice()[ edge_chunk_meta.offset as usize..(edge_chunk_meta.offset + edge_chunk_meta.capacity) as usize]
194 }
195
196 #[inline(always)]
197 fn edges_as_ptr(&self, vertex: VHandle) -> FatPtr<Edge> {
198 let edge_chunk_meta = self.vertex_entries[vertex as usize];
199 unsafe{
200 let start = self.edges.as_ptr().add(edge_chunk_meta.offset as usize);
201 let end = start.add(edge_chunk_meta.len as usize);
202 FatPtr::new(start, end)
203 }
204 }
205
206 #[inline(always)]
207 fn edges_as_mut_ptr(&mut self, vertex: VHandle) -> FatPtrMut<Edge> {
208 let edge_chunk_meta = self.vertex_entries[vertex as usize];
209 unsafe{
210 let start = self.edges.as_mut_ptr().add(edge_chunk_meta.offset as usize);
211 let end = start.add(edge_chunk_meta.len as usize);
212 FatPtrMut::new(start, end)
213 }
214 }
215 #[inline(always)]
216 fn edges_is_empty(&self, handle: VHandle) -> bool {
217 self.edges_len(handle) == 0
218 }
219
220 #[inline(always)]
221 fn edges_len(&self, handle: VHandle) -> usize {
222 self.vertex_entries[handle as usize].len as usize
223 }
224 #[inline(always)]
225 fn edges_capacity(&self, handle: VHandle) -> usize {
226 self.vertex_entries[handle as usize].capacity as usize
227 }
228 #[inline(always)]
229 fn edges_index(&self, vertex: VHandle) -> usize {
230 self.vertex_entries[vertex as usize].offset as usize
231 }
232 #[inline(always)]
233 fn iter(&self) -> impl Iterator<Item=&Edge> {
234 EdgeStorageIter::new(self)
235 }
236
237 #[inline(always)]
238 fn iter_mut(&mut self) -> impl Iterator<Item=&mut Edge> {
239 EdgeStorageIterMut::new(self)
240 }
241
242 #[inline(always)]
243 fn edges_iter(&self, handle: VHandle) -> impl Iterator<Item=&Edge> {
244 let index = self.edges_index(handle);
245 let end = index + self.edges_len(handle);
246 self.edges.iter_range(index, end)
247 }
248
249 #[inline(always)]
250 fn edges_iter_mut(&mut self, handle: VHandle) -> impl Iterator<Item=&mut Edge> {
251 let index = self.edges_index(handle);
252 let end = index + self.edges_len(handle);
253 self.edges.iter_range_mut(index, end)
254 }
255
256 unsafe fn edges_iter_mut_unchecked(&mut self, handle: VHandle) -> impl Iterator<Item=&mut Edge> {
257 self.edges.iter_range_mut_unchecked(self.edges_index(handle), self.edges_len(handle))
258 }
259}
260impl Clone for EdgeStorage {
261 fn clone(&self) -> Self {
262 EdgeStorage {
263 reserve: self.reserve,
264 edges: self.edges.clone(),
265 vertex_entries: self.vertex_entries.clone(),
266 }
267 }
268
269 fn clone_from(&mut self, source: &Self) {
270 self.reserve = source.reserve;
271 self.edges.clone_from(&source.edges);
272 self.vertex_entries.clone_from(&source.vertex_entries);
273 }
274}
275
276impl Index<usize> for EdgeStorage {
277 type Output = Edge;
278 fn index(&self, index: usize) -> &Self::Output {
279 &self.edges[index]
280 }
281}
282
283impl IndexMut<usize> for EdgeStorage {
284 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
285 &mut self.edges[index]
286 }
287}
288
289impl EdgeManipulate for EdgeStorage {}
290
291impl WeightedEdgeManipulate for EdgeStorage {}