eta_graph/
edge_storage.rs

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    /// Creates a new graph with the assumption that the usage will be dynamic.
109    /// It will create the graph with high reserve count of 50 to avoid reallocations.
110    pub fn new_large() -> Self {
111        EdgeStorage {
112            reserve: 50,
113            edges: Array::new(0),
114            vertex_entries: Vec::new(),
115        }
116    }
117    /// Creates a new graph with a custom reserve
118    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    /// Creates a new graph with the assumption that the graph size is known ahead of time. No reserve.
127    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); // Swap the last element for the empty one
157                    *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 {}