process_mining/event_log/ocel/linked_ocel/
id_linked_ocel.rs1use std::collections::HashMap;
2
3use crate::{
4 ocel::ocel_struct::{OCELEvent, OCELObject},
5 OCEL,
6};
7
8use super::LinkedOCELAccess;
9
10impl<'a> LinkedOCELAccess<'a, EventID<'a>, ObjectID<'a>, OCELEvent, OCELObject>
11 for IDLinkedOCEL<'a>
12{
13 fn get_evs_of_type(&'a self, ev_type: &'_ str) -> impl Iterator<Item = &'a OCELEvent> {
14 self.events_per_type
15 .get(ev_type)
16 .into_iter()
17 .flatten()
18 .copied()
19 }
20
21 fn get_obs_of_type(&'a self, ob_type: &'_ str) -> impl Iterator<Item = &'a OCELObject> {
22 self.objects_per_type
23 .get(ob_type)
24 .into_iter()
25 .flatten()
26 .copied()
27 }
28
29 fn get_ev(&'a self, ev_id: &EventID<'a>) -> &'a OCELEvent {
30 self.events.get(ev_id).unwrap()
31 }
32
33 fn get_ob(&'a self, ob_id: &ObjectID<'a>) -> &'a OCELObject {
34 self.objects.get(ob_id).unwrap()
35 }
36
37 fn get_e2o(&'a self, index: &EventID<'a>) -> impl Iterator<Item = (&'a str, &'a OCELObject)> {
38 self.e2o_rel.get(index).into_iter().flatten().copied()
39 }
40
41 fn get_e2o_rev(
42 &'a self,
43 index: &ObjectID<'a>,
44 ) -> impl Iterator<Item = (&'a str, &'a OCELEvent)> {
45 self.e2o_rel_rev.get(index).into_iter().flatten().copied()
46 }
47
48 fn get_o2o(&'a self, index: &ObjectID<'a>) -> impl Iterator<Item = (&'a str, &'a OCELObject)> {
49 self.o2o_rel.get(index).into_iter().flatten().copied()
50 }
51
52 fn get_o2o_rev(
53 &'a self,
54 index: &ObjectID<'a>,
55 ) -> impl Iterator<Item = (&'a str, &'a OCELObject)> {
56 self.o2o_rel_rev.get(index).into_iter().flatten().copied()
57 }
58
59 fn get_ev_types(&'a self) -> impl Iterator<Item = &'a str> {
60 self.events_per_type.keys().copied()
61 }
62
63 fn get_ob_types(&'a self) -> impl Iterator<Item = &'a str> {
64 self.objects_per_type.keys().copied()
65 }
66
67 fn get_all_evs(&'a self) -> impl Iterator<Item = &'a OCELEvent> {
68 self.ocel.events.iter()
69 }
70
71 fn get_all_obs(&'a self) -> impl Iterator<Item = &'a OCELObject> {
72 self.ocel.objects.iter()
73 }
74
75 fn get_all_evs_ref(&'a self) -> impl Iterator<Item = &'a EventID<'a>> {
76 self.events.iter().map(|e| e.0)
77 }
78
79 fn get_all_obs_ref(&'a self) -> impl Iterator<Item = &'a ObjectID<'a>> {
80 self.objects.iter().map(|o| o.0)
81 }
82}
83
84#[derive(Debug, Clone, PartialEq, Eq, Hash)]
85pub struct ObjectID<'a>(&'a str);
87
88impl<'a> From<&'a OCELObject> for ObjectID<'a> {
89 fn from(value: &'a OCELObject) -> Self {
90 Self(value.id.as_str())
91 }
92}
93
94#[derive(Debug, Clone, PartialEq, Eq, Hash)]
95pub struct EventID<'a>(&'a str);
97
98impl<'a> From<&'a OCELEvent> for EventID<'a> {
99 fn from(value: &'a OCELEvent) -> Self {
100 Self(value.id.as_str())
101 }
102}
103
104#[derive(Debug, Clone)]
105pub struct IDLinkedOCEL<'a> {
107 pub ocel: &'a OCEL,
109 events: HashMap<EventID<'a>, &'a OCELEvent>,
110 objects: HashMap<ObjectID<'a>, &'a OCELObject>,
111 events_per_type: HashMap<&'a str, Vec<&'a OCELEvent>>,
112 objects_per_type: HashMap<&'a str, Vec<&'a OCELObject>>,
113 e2o_rel: HashMap<EventID<'a>, Vec<(&'a str, &'a OCELObject)>>,
114 o2o_rel: HashMap<ObjectID<'a>, Vec<(&'a str, &'a OCELObject)>>,
115 e2o_rel_rev: HashMap<ObjectID<'a>, Vec<(&'a str, &'a OCELEvent)>>,
116 o2o_rel_rev: HashMap<ObjectID<'a>, Vec<(&'a str, &'a OCELObject)>>,
117}
118
119impl<'a> IDLinkedOCEL<'a> {
120 pub fn from_ocel(ocel: &'a OCEL) -> Self {
122 Self::from(ocel)
123 }
124}
125
126impl<'a> From<&'a OCEL> for IDLinkedOCEL<'a> {
127 fn from(ocel: &'a OCEL) -> Self {
128 let events: HashMap<_, _> = ocel.events.iter().map(|e| (EventID(&e.id), e)).collect();
129 let objects: HashMap<_, _> = ocel.objects.iter().map(|o| (ObjectID(&o.id), o)).collect();
130 let mut e2o_rel_rev: HashMap<ObjectID<'a>, Vec<(&str, &OCELEvent)>> = HashMap::new();
131 let e2o_rel = events
132 .values()
133 .map(|e| {
134 let e_id: EventID<'_> = EventID(&e.id);
135 (
136 e_id,
137 e.relationships
138 .iter()
139 .flat_map(|rel| {
140 let obj_id: ObjectID<'_> = ObjectID(&rel.object_id);
141 let qualifier = rel.qualifier.as_str();
142 e2o_rel_rev.entry(obj_id).or_default().push((qualifier, e));
143 let ob = objects.get(&(ObjectID(&rel.object_id)))?;
144 Some((qualifier, *ob))
145 })
146 .collect(),
147 )
148 })
149 .collect();
150
151 let mut o2o_rel_rev: HashMap<ObjectID<'_>, Vec<(&'a str, &OCELObject)>> = HashMap::new();
152
153 let o2o_rel = objects
154 .values()
155 .map(|o| {
156 (
157 ObjectID(&o.id),
158 o.relationships
159 .iter()
160 .flat_map(|rel| {
161 let qualifier = rel.qualifier.as_str();
162 let obj2_id: ObjectID<'_> = ObjectID(&rel.object_id);
163 o2o_rel_rev.entry(obj2_id).or_default().push((qualifier, o));
164 let ob = objects.get(&ObjectID(&rel.object_id))?;
165 Some((qualifier, *ob))
166 })
167 .collect(),
168 )
169 })
170 .collect();
171 let events_per_type = ocel
172 .event_types
173 .iter()
174 .map(|et| {
175 (
176 et.name.as_str(),
177 ocel.events
178 .iter()
179 .filter(|e| e.event_type == et.name)
180 .collect(),
181 )
182 })
183 .collect();
184
185 let objects_per_type = ocel
186 .object_types
187 .iter()
188 .map(|et| {
189 (
190 et.name.as_str(),
191 ocel.objects
192 .iter()
193 .filter(|e| e.object_type == et.name)
194 .collect(),
195 )
196 })
197 .collect();
198 Self {
199 ocel,
200 events,
201 objects,
202 events_per_type,
203 objects_per_type,
204 e2o_rel,
205 o2o_rel,
206 e2o_rel_rev,
207 o2o_rel_rev,
208 }
209 }
210}
211
212#[derive(Debug, Clone)]
218pub struct OwnedIDLinkedOCEL<'a> {
219 ocel: OCEL,
220 pub linked_ocel: IDLinkedOCEL<'a>,
222}
223
224impl<'a> OwnedIDLinkedOCEL<'a> {
225 pub fn from_ocel(ocel: OCEL) -> Self {
227 Self::from(ocel)
228 }
229 pub fn into_inner(self) -> OCEL {
231 self.ocel
232 }
233 pub fn ocel_ref(&'a self) -> &'a OCEL {
235 &self.ocel
236 }
237}
238
239impl From<OCEL> for OwnedIDLinkedOCEL<'_> {
240 fn from(ocel: OCEL) -> Self {
241 let ocel_ref = unsafe { &*(&ocel as *const OCEL) };
242 OwnedIDLinkedOCEL {
243 ocel,
244 linked_ocel: (ocel_ref).into(),
245 }
246 }
247}
248
249impl<'a> LinkedOCELAccess<'a, EventID<'a>, ObjectID<'a>, OCELEvent, OCELObject>
250 for OwnedIDLinkedOCEL<'a>
251{
252 fn get_evs_of_type(&'a self, ev_type: &'_ str) -> impl Iterator<Item = &'a OCELEvent> {
253 self.linked_ocel.get_evs_of_type(ev_type)
254 }
255
256 fn get_obs_of_type(&'a self, ob_type: &'_ str) -> impl Iterator<Item = &'a OCELObject> {
257 self.linked_ocel.get_obs_of_type(ob_type)
258 }
259
260 fn get_ev(&'a self, index: &EventID<'a>) -> &'a OCELEvent {
261 self.linked_ocel.get_ev(index)
262 }
263
264 fn get_ob(&'a self, index: &ObjectID<'a>) -> &'a OCELObject {
265 self.linked_ocel.get_ob(index)
266 }
267
268 fn get_e2o(&'a self, index: &EventID<'a>) -> impl Iterator<Item = (&'a str, &'a OCELObject)> {
269 self.linked_ocel.get_e2o(index)
270 }
271
272 fn get_e2o_rev(
273 &'a self,
274 index: &ObjectID<'a>,
275 ) -> impl Iterator<Item = (&'a str, &'a OCELEvent)> {
276 self.linked_ocel.get_e2o_rev(index)
277 }
278
279 fn get_o2o(&'a self, index: &ObjectID<'a>) -> impl Iterator<Item = (&'a str, &'a OCELObject)> {
280 self.linked_ocel.get_o2o(index)
281 }
282
283 fn get_o2o_rev(
284 &'a self,
285 index: &ObjectID<'a>,
286 ) -> impl Iterator<Item = (&'a str, &'a OCELObject)> {
287 self.linked_ocel.get_o2o_rev(index)
288 }
289
290 fn get_ev_types(&'a self) -> impl Iterator<Item = &'a str> {
291 self.linked_ocel.get_ev_types()
292 }
293
294 fn get_ob_types(&'a self) -> impl Iterator<Item = &'a str> {
295 self.linked_ocel.get_ob_types()
296 }
297
298 fn get_all_evs(&'a self) -> impl Iterator<Item = &'a OCELEvent> {
299 self.linked_ocel.get_all_evs()
300 }
301
302 fn get_all_obs(&'a self) -> impl Iterator<Item = &'a OCELObject> {
303 self.linked_ocel.get_all_obs()
304 }
305
306 fn get_all_evs_ref(&'a self) -> impl Iterator<Item = &'a EventID<'a>> {
307 self.linked_ocel.get_all_evs_ref()
308 }
309
310 fn get_all_obs_ref(&'a self) -> impl Iterator<Item = &'a ObjectID<'a>> {
311 self.linked_ocel.get_all_obs_ref()
312 }
313}