diff --git a/All.sln b/All.sln index c18b8ba9f..0d8a575e7 100644 --- a/All.sln +++ b/All.sln @@ -132,9 +132,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "misc", "misc", "{2918C7E3-3 Ficus\Readme.md = Ficus\Readme.md EndProjectSection EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Salve", "Salve", "{BA9BD6EC-204D-40AA-86A7-E70087EB9A1D}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UtilProjects", "UtilProjects", "{5EB4BB7D-E983-489E-A220-C99610C5FF01}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Salve", "Salve\Salve.csproj", "{11FB9788-D067-4AD5-A17D-4685DE9DD366}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Salve", "util_projects\Salve\Salve.csproj", "{A3A62DBD-B92F-46F2-9104-F39A6E606148}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -242,10 +242,10 @@ Global {1BBDEB95-1084-4981-AE5A-EFFC74E095E4}.Debug|Any CPU.Build.0 = Debug|Any CPU {1BBDEB95-1084-4981-AE5A-EFFC74E095E4}.Release|Any CPU.ActiveCfg = Release|Any CPU {1BBDEB95-1084-4981-AE5A-EFFC74E095E4}.Release|Any CPU.Build.0 = Release|Any CPU - {11FB9788-D067-4AD5-A17D-4685DE9DD366}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {11FB9788-D067-4AD5-A17D-4685DE9DD366}.Debug|Any CPU.Build.0 = Debug|Any CPU - {11FB9788-D067-4AD5-A17D-4685DE9DD366}.Release|Any CPU.ActiveCfg = Release|Any CPU - {11FB9788-D067-4AD5-A17D-4685DE9DD366}.Release|Any CPU.Build.0 = Release|Any CPU + {A3A62DBD-B92F-46F2-9104-F39A6E606148}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A3A62DBD-B92F-46F2-9104-F39A6E606148}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A3A62DBD-B92F-46F2-9104-F39A6E606148}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A3A62DBD-B92F-46F2-9104-F39A6E606148}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {FEF48EF9-EDFC-4464-8942-64FC9FF000CA} = {C3E829BA-4C31-4F55-BF4D-C0D11B0B70B4} @@ -285,6 +285,6 @@ Global {B1223284-182E-4C3A-92CD-F59FBD42FFD6} = {0EC07BD3-AB92-48A0-B68B-05B3F2A767A3} {1BBDEB95-1084-4981-AE5A-EFFC74E095E4} = {D50BD31E-296B-468E-817A-60AF1CE7A759} {2918C7E3-3FC8-48A5-ADDF-8358E888B40C} = {5F2E0AEA-6AAF-4130-B486-A5F4F5A8A4BD} - {11FB9788-D067-4AD5-A17D-4685DE9DD366} = {BA9BD6EC-204D-40AA-86A7-E70087EB9A1D} + {A3A62DBD-B92F-46F2-9104-F39A6E606148} = {5EB4BB7D-E983-489E-A220-C99610C5FF01} EndGlobalSection EndGlobal diff --git a/Ficus/src/python/ficus/grpc_pipelines/constants.py b/Ficus/src/python/ficus/grpc_pipelines/constants.py index 6a3edaebe..b8066135c 100644 --- a/Ficus/src/python/ficus/grpc_pipelines/constants.py +++ b/Ficus/src/python/ficus/grpc_pipelines/constants.py @@ -149,7 +149,7 @@ const_abstract_timeline_diagram = 'AbstractTimelineDiagram' const_clusterize_traces_k_means_grid_search = 'ClusterizeLogTracesKMeansGridSearch' const_clusterize_traces_dbscan_grid_search = 'ClusterizeLogTracesDbscanGridSearch' -const_discover_root_sequence_graph = 'DiscoverRootSequenceGraph' +const_discover_ecfg = 'DiscoverECFG' const_discover_loops_strict = 'DiscoverLoopsStrict' const_discover_traces_timeline_diagram = 'DiscoverTracesTimelineDiagram' diff --git a/Ficus/src/python/ficus/grpc_pipelines/discovery_parts.py b/Ficus/src/python/ficus/grpc_pipelines/discovery_parts.py index ac8f1a7fd..0fe4ae778 100644 --- a/Ficus/src/python/ficus/grpc_pipelines/discovery_parts.py +++ b/Ficus/src/python/ficus/grpc_pipelines/discovery_parts.py @@ -248,7 +248,7 @@ class DiscoverDirectlyFollowsGraphStream(PipelinePart): def to_grpc_part(self) -> GrpcPipelinePartBase: return _create_default_discovery_part(const_discover_directly_follows_graph_stream) -class DiscoverRootSequenceGraph(PipelinePart): +class DiscoverECFG(PipelinePart): def __init__(self, root_sequence_kind: RootSequenceKind = RootSequenceKind.FindBest, merge_sequences_of_events: bool = True): @@ -261,4 +261,4 @@ def to_grpc_part(self) -> GrpcPipelinePartBase: append_root_sequence_kind(config, const_root_sequence_kind, self.root_sequence_kind) append_bool_value(config, const_merge_sequences_of_events, self.merge_sequences_of_events) - return GrpcPipelinePartBase(defaultPart=create_default_pipeline_part(const_discover_root_sequence_graph, config)) + return GrpcPipelinePartBase(defaultPart=create_default_pipeline_part(const_discover_ecfg, config)) diff --git a/Ficus/src/python/tests/grpc_pipelines/annotations/test_ocel_annotation.py b/Ficus/src/python/tests/grpc_pipelines/annotations/test_ocel_annotation.py index b3c03dfff..c44bd2572 100644 --- a/Ficus/src/python/tests/grpc_pipelines/annotations/test_ocel_annotation.py +++ b/Ficus/src/python/tests/grpc_pipelines/annotations/test_ocel_annotation.py @@ -98,8 +98,8 @@ def _execute_ocel_annotation_test(test_name: str, log_name: str, filter_parts: l pipeline.parts.extend([ AddStartArtificialEvents(), - DiscoverRootSequenceGraph(root_sequence_kind=RootSequenceKind.FindBest, - merge_sequences_of_events=False), + DiscoverECFG(root_sequence_kind=RootSequenceKind.FindBest, + merge_sequences_of_events=False), CreateDagOcelAnnotation(), AssertCorrectOcelAnnotation(test_name) ]) diff --git a/Ficus/src/rust/Cargo.lock b/Ficus/src/rust/Cargo.lock index 689fc7e5c..1a11f5b29 100644 --- a/Ficus/src/rust/Cargo.lock +++ b/Ficus/src/rust/Cargo.lock @@ -567,7 +567,6 @@ version = "0.1.0" dependencies = [ "approx 0.5.1", "bxes", - "bxes_kafka", "chrono", "derive-new", "enum-display", @@ -581,24 +580,17 @@ dependencies = [ "linfa-clustering", "linfa-nn", "log", - "nameof", "ndarray", "num-traits", "once_cell", "paste", - "prost", - "prost-types", "quick-xml", "rand 0.8.5", - "rdkafka", "serde", "serde_json", "stopwatch", "termgraph", - "tokio", - "tokio-stream", "tonic", - "tonic-build", "uuid", ] @@ -606,11 +598,23 @@ dependencies = [ name = "ficus_backend" version = "0.1.0" dependencies = [ + "bxes", + "bxes_kafka", + "chrono", "colog", "ficus", + "futures", "log", + "nameof", + "prost", + "prost-types", + "rdkafka", + "serde_json", "tokio", + "tokio-stream", "tonic", + "tonic-build", + "uuid", ] [[package]] diff --git a/Ficus/src/rust/ficus/Cargo.toml b/Ficus/src/rust/ficus/Cargo.toml index 344bffeea..48b78714a 100644 --- a/Ficus/src/rust/ficus/Cargo.toml +++ b/Ficus/src/rust/ficus/Cargo.toml @@ -1,8 +1,7 @@ [package] name = "ficus" version = "0.1.0" -edition = "2021" -build = "build.rs" +edition = "2024" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -11,13 +10,8 @@ chrono = "0.4.42" quick-xml = "0.29.0" lazycell = "1.3" tonic = "0.9.2" -prost = "0.11.9" -prost-types = "0.11.9" -tokio = { version = "1.49.0", features = ["rt-multi-thread"] } futures = "0.3.31" -tokio-stream = "0.1.17" rand = "0.8.5" -nameof = "1.3.0" once_cell = "1.21.3" fancy-regex = "0.11.0" stopwatch = "0.0.7" @@ -26,9 +20,7 @@ linfa-clustering = "0.7.1" linfa-nn = "0.7.2" ndarray = "0.15.6" bxes = { path = "../../../../bxes/src/rust/bxes/" } -bxes_kafka = { path = "../../../../bxes/src/rust/bxes_kafka" } lazy_static = "1.5.0" -rdkafka = { version = "0.36.2", features = ["cmake-build"] } log = "0.4.29" num-traits = "0.2.19" approx = "0.5.1" @@ -48,6 +40,3 @@ features = [ "fast-rng", # Use a faster (but still sufficiently random) RNG "macro-diagnostics", # Enable better diagnostics for compile-time UUIDs ] - -[build-dependencies] -tonic-build = "0.9.2" diff --git a/Ficus/src/rust/ficus/src/event_log/bxes/bxes_to_xes_converter.rs b/Ficus/src/rust/ficus/src/event_log/bxes/bxes_to_xes_converter.rs index 7fa563426..2bbd551f4 100644 --- a/Ficus/src/rust/ficus/src/event_log/bxes/bxes_to_xes_converter.rs +++ b/Ficus/src/rust/ficus/src/event_log/bxes/bxes_to_xes_converter.rs @@ -1,5 +1,3 @@ -use std::{cell::RefCell, collections::HashMap, rc::Rc}; - use bxes::{ models::{ domain::{ @@ -15,6 +13,7 @@ use bxes::{ }, }; use chrono::{TimeZone, Utc}; +use std::{cell::RefCell, collections::HashMap, fmt::Display, rc::Rc}; use super::conversions::{bxes_value_to_payload_value, global_type_to_string}; use crate::event_log::{ @@ -33,12 +32,15 @@ pub enum BxesToXesReadError { ConversionError(String), } -impl ToString for BxesToXesReadError { - fn to_string(&self) -> String { - match self { - BxesToXesReadError::BxesReadError(err) => err.to_string(), - BxesToXesReadError::ConversionError(err) => err.to_string(), - } +impl Display for BxesToXesReadError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str( + match self { + BxesToXesReadError::BxesReadError(err) => err.to_string(), + BxesToXesReadError::ConversionError(err) => err.to_string(), + } + .as_str(), + ) } } @@ -197,7 +199,7 @@ fn create_xes_payload( return Err(BxesToXesReadError::ConversionError(message)); }; - payload.insert(key, bxes_value_to_payload_value(&value)); + payload.insert(key, bxes_value_to_payload_value(value)); } Ok(Some(payload)) diff --git a/Ficus/src/rust/ficus/src/event_log/bxes/conversions.rs b/Ficus/src/rust/ficus/src/event_log/bxes/conversions.rs index a8d483c42..402033123 100644 --- a/Ficus/src/rust/ficus/src/event_log/bxes/conversions.rs +++ b/Ficus/src/rust/ficus/src/event_log/bxes/conversions.rs @@ -96,7 +96,7 @@ pub(super) fn payload_value_to_bxes_value(value: &EventPayloadValue) -> BxesValu EventPayloadValue::Float64(value) => BxesValue::Float64(*value), EventPayloadValue::Uint32(value) => BxesValue::Uint32(*value), EventPayloadValue::Uint64(value) => BxesValue::Uint64(*value), - EventPayloadValue::Guid(value) => BxesValue::Guid(value.clone()), + EventPayloadValue::Guid(value) => BxesValue::Guid(*value), EventPayloadValue::Timestamp(value) => BxesValue::Timestamp(*value), EventPayloadValue::Lifecycle(lifecycle) => match convert_xes_to_bxes_lifecycle(lifecycle) { bxes::models::domain::bxes_lifecycle::Lifecycle::Braf(braf) => BxesValue::BrafLifecycle(braf), diff --git a/Ficus/src/rust/ficus/src/event_log/bxes/xes_to_bxes_converter.rs b/Ficus/src/rust/ficus/src/event_log/bxes/xes_to_bxes_converter.rs index 137aba473..0f3d50196 100644 --- a/Ficus/src/rust/ficus/src/event_log/bxes/xes_to_bxes_converter.rs +++ b/Ficus/src/rust/ficus/src/event_log/bxes/xes_to_bxes_converter.rs @@ -1,4 +1,4 @@ -use std::rc::Rc; +use std::{fmt::Display, rc::Rc}; use super::conversions::{parse_entity_kind, payload_value_to_bxes_value}; use crate::event_log::{ @@ -30,12 +30,15 @@ pub enum XesToBxesWriterError { ConversionError(String), } -impl ToString for XesToBxesWriterError { - fn to_string(&self) -> String { - match self { - XesToBxesWriterError::BxesWriteError(err) => err.to_string(), - XesToBxesWriterError::ConversionError(err) => err.to_owned(), - } +impl Display for XesToBxesWriterError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str( + match self { + XesToBxesWriterError::BxesWriteError(err) => err.to_string(), + XesToBxesWriterError::ConversionError(err) => err.to_owned(), + } + .as_str(), + ) } } @@ -94,7 +97,7 @@ fn create_bxes_traces(log: &XesEventLogImpl) -> Vec { } fn create_bxes_event(log: &XesEventLogImpl, event: &XesEventImpl) -> BxesEvent { - let bxes_event = BxesEvent { + BxesEvent { name: Rc::new(Box::new(BxesValue::String(event.name_pointer().clone()))), timestamp: event.timestamp().timestamp_nanos_opt().expect("timestamp_nanos_opt"), attributes: Some( @@ -102,12 +105,10 @@ fn create_bxes_event(log: &XesEventLogImpl, event: &XesEventImpl) -> BxesEvent { .ordered_payload() .iter() .filter(|kv| is_not_default_attribute(log, kv)) - .map(|kv| kv_pair_to_bxes_pair(kv)) + .map(kv_pair_to_bxes_pair) .collect(), ), - }; - - bxes_event + } } fn is_not_default_attribute(log: &XesEventLogImpl, kv: &(&String, &EventPayloadValue)) -> bool { @@ -138,7 +139,7 @@ fn create_bxes_classifiers(log: &XesEventLogImpl) -> Vec { } fn create_bxes_extensions(log: &XesEventLogImpl) -> Vec { - log.extensions().iter().map(|e| convert_to_bxes_extension(e)).collect() + log.extensions().iter().map(convert_to_bxes_extension).collect() } fn convert_to_bxes_extension(e: &XesEventLogExtension) -> BxesExtension { @@ -154,7 +155,7 @@ fn create_bxes_globals(log: &XesEventLogImpl) -> Result, XesToBx for xes_global in log.ordered_globals().iter() { globals.push(BxesGlobal { entity_kind: parse_entity_kind(xes_global.0.as_str())?, - globals: xes_global.1.iter().map(|kv| convert_to_bxes_global_attribute(kv)).collect(), + globals: xes_global.1.iter().map(convert_to_bxes_global_attribute).collect(), }) } diff --git a/Ficus/src/rust/ficus/src/event_log/core/event/event_base.rs b/Ficus/src/rust/ficus/src/event_log/core/event/event_base.rs index 7fead006a..bad338d03 100644 --- a/Ficus/src/rust/ficus/src/event_log/core/event/event_base.rs +++ b/Ficus/src/rust/ficus/src/event_log/core/event/event_base.rs @@ -16,7 +16,7 @@ impl EventBase { Self { name, timestamp, - user_data: UserDataImpl::new(), + user_data: Default::default(), } } } @@ -25,7 +25,7 @@ impl Clone for EventBase { fn clone(&self) -> Self { Self { name: self.name.clone(), - timestamp: self.timestamp.clone(), + timestamp: self.timestamp, user_data: self.user_data.clone(), } } diff --git a/Ficus/src/rust/ficus/src/event_log/core/event/event_hasher.rs b/Ficus/src/rust/ficus/src/event_log/core/event/event_hasher.rs index a9dc7ed84..be744339c 100644 --- a/Ficus/src/rust/ficus/src/event_log/core/event/event_hasher.rs +++ b/Ficus/src/rust/ficus/src/event_log/core/event/event_hasher.rs @@ -14,14 +14,9 @@ where fn hash(&self, event: &TEvent) -> u64; } +#[derive(Default)] pub struct NameEventHasher; -impl NameEventHasher { - pub fn new() -> Self { - Self {} - } -} - impl EventHasher for NameEventHasher where TEvent: Event, @@ -59,7 +54,7 @@ where } impl RegexEventHasher { - pub fn new(regex: &String) -> Result { + pub fn new(regex: &str) -> Result { match Regex::new(regex) { Ok(regex) => Ok(RegexEventHasher { regex }), Err(error) => Err(error), diff --git a/Ficus/src/rust/ficus/src/event_log/core/event/events_holder.rs b/Ficus/src/rust/ficus/src/event_log/core/event/events_holder.rs index d20d7aae5..c668eef29 100644 --- a/Ficus/src/rust/ficus/src/event_log/core/event/events_holder.rs +++ b/Ficus/src/rust/ficus/src/event_log/core/event/events_holder.rs @@ -25,10 +25,7 @@ where { fn clone(&self) -> Self { Self { - events: (&self.events) - .into_iter() - .map(|ptr| Rc::new(RefCell::new(ptr.borrow().clone()))) - .collect(), + events: self.events.iter().map(|ptr| Rc::new(RefCell::new(ptr.borrow().clone()))).collect(), events_sequence_info: LazyCell::new(), events_positions: LazyCell::new(), @@ -70,9 +67,10 @@ where { let mut new_events = vec![]; let events = &self.events; - for index in 0..events.len() { - if !predicate(&events[index].borrow()) { - new_events.push(events[index].clone()) + + for (index, event) in events.iter().enumerate() { + if !predicate(&event.borrow()) { + new_events.push(event.clone()) } else { debug!("Removing event at index {}: {:?}", index, events[index].borrow()) } @@ -164,11 +162,9 @@ impl EventsPositions { TEvent: Event, { let mut positions = HashMap::new(); - let mut index = 0; - for event in events.events() { + for (index, event) in events.events().iter().enumerate() { add_to_list_in_map(&mut positions, event.borrow().name(), index); - index += 1; } EventsPositions { positions } @@ -176,7 +172,7 @@ impl EventsPositions { } impl TraceEventsPositions for EventsPositions { - fn event_positions(&self, event_class: &String) -> Option<&Vec> { + fn event_positions(&self, event_class: &str) -> Option<&Vec> { self.positions.get(event_class) } } diff --git a/Ficus/src/rust/ficus/src/event_log/core/event/lifecycle/braf_lifecycle.rs b/Ficus/src/rust/ficus/src/event_log/core/event/lifecycle/braf_lifecycle.rs index 7166cf5ed..54ced2e96 100644 --- a/Ficus/src/rust/ficus/src/event_log/core/event/lifecycle/braf_lifecycle.rs +++ b/Ficus/src/rust/ficus/src/event_log/core/event/lifecycle/braf_lifecycle.rs @@ -27,26 +27,26 @@ pub enum XesBrafLifecycle { OpenRunningSuspended = 19, } -const UNSPECIFIED: &'static str = "Unspecified"; -const CLOSED: &'static str = "Closed"; -const CLOSED_CANCELLED: &'static str = "Closed.Cancelled"; -const CLOSED_CANCELLED_ABORTED: &'static str = "Closed.Cancelled.Aborted"; -const CLOSED_CANCELLED_ERROR: &'static str = "Closed.Cancelled.Error"; -const CLOSED_CANCELLED_EXITED: &'static str = "Closed.Cancelled.Exited"; -const CLOSED_CANCELLED_OBSOLETE: &'static str = "Closed.Cancelled.Obsolete"; -const CLOSED_CANCELLED_TERMINATED: &'static str = "Closed.Cancelled.Terminated"; -const COMPLETED: &'static str = "Completed"; -const COMPLETED_FAILED: &'static str = "Completed.Failed"; -const COMPLETED_SUCCESS: &'static str = "Completed.Success"; -const OPEN: &'static str = "Open"; -const OPEN_NOTRUNNING: &'static str = "Open.NotRunning"; -const OPEN_NOTRUNNING_ASSIGNED: &'static str = "Open.NotRunning.Assigned"; -const OPEN_NOTRUNNING_RESERVED: &'static str = "Open.NotRunning.Reserved"; -const OPEN_NOTRUNNING_SUSPENDED_ASSIGNED: &'static str = "Open.NotRunning.Suspended.Assigned"; -const OPEN_NOTRUNNING_SUSPENDED_RESERVED: &'static str = "Open.NotRunning.Suspended.Reserved"; -const OPEN_RUNNING: &'static str = "Open.Running"; -const OPEN_RUNNING_INPROGRESS: &'static str = "Open.Running.InProgress"; -const OPEN_RUNNING_SUSPENDED: &'static str = "Open.Running.Suspended"; +const UNSPECIFIED: &str = "Unspecified"; +const CLOSED: &str = "Closed"; +const CLOSED_CANCELLED: &str = "Closed.Cancelled"; +const CLOSED_CANCELLED_ABORTED: &str = "Closed.Cancelled.Aborted"; +const CLOSED_CANCELLED_ERROR: &str = "Closed.Cancelled.Error"; +const CLOSED_CANCELLED_EXITED: &str = "Closed.Cancelled.Exited"; +const CLOSED_CANCELLED_OBSOLETE: &str = "Closed.Cancelled.Obsolete"; +const CLOSED_CANCELLED_TERMINATED: &str = "Closed.Cancelled.Terminated"; +const COMPLETED: &str = "Completed"; +const COMPLETED_FAILED: &str = "Completed.Failed"; +const COMPLETED_SUCCESS: &str = "Completed.Success"; +const OPEN: &str = "Open"; +const OPEN_NOTRUNNING: &str = "Open.NotRunning"; +const OPEN_NOTRUNNING_ASSIGNED: &str = "Open.NotRunning.Assigned"; +const OPEN_NOTRUNNING_RESERVED: &str = "Open.NotRunning.Reserved"; +const OPEN_NOTRUNNING_SUSPENDED_ASSIGNED: &str = "Open.NotRunning.Suspended.Assigned"; +const OPEN_NOTRUNNING_SUSPENDED_RESERVED: &str = "Open.NotRunning.Suspended.Reserved"; +const OPEN_RUNNING: &str = "Open.Running"; +const OPEN_RUNNING_INPROGRESS: &str = "Open.Running.InProgress"; +const OPEN_RUNNING_SUSPENDED: &str = "Open.Running.Suspended"; static STRINGS_TO_LIFECYCLE: Lazy> = Lazy::new(|| { HashMap::from_iter(vec![ @@ -83,7 +83,7 @@ static LIFECYCLE_TO_STRINGS: Lazy> = Laz impl Display for XesBrafLifecycle { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", LIFECYCLE_TO_STRINGS.get(&self).unwrap().to_string()) + write!(f, "{}", LIFECYCLE_TO_STRINGS.get(self).unwrap()) } } diff --git a/Ficus/src/rust/ficus/src/event_log/core/event/lifecycle/standard_lifecycle.rs b/Ficus/src/rust/ficus/src/event_log/core/event/lifecycle/standard_lifecycle.rs index a748f70fe..72257cfe8 100644 --- a/Ficus/src/rust/ficus/src/event_log/core/event/lifecycle/standard_lifecycle.rs +++ b/Ficus/src/rust/ficus/src/event_log/core/event/lifecycle/standard_lifecycle.rs @@ -21,20 +21,20 @@ pub enum XesStandardLifecycle { Withdraw = 13, } -const SCHEDULE: &'static str = "schedule"; -const START: &'static str = "start"; -const COMPLETE: &'static str = "complete"; -const UNKNOWN: &'static str = "unknown"; -const UNSPECIFIED: &'static str = "unspecified"; -const ASSIGN: &'static str = "assign"; -const ATE_ABORT: &'static str = "ate_abort"; -const AUTOSKIP: &'static str = "autoskip"; -const MANUAL_SKIP: &'static str = "manualskip"; -const PI_ABORT: &'static str = "pi_abort"; -const RE_ASSIGN: &'static str = "reassign"; -const RESUME: &'static str = "resume"; -const SUSPEND: &'static str = "suspend"; -const WITHDRAW: &'static str = "withdraw"; +const SCHEDULE: &str = "schedule"; +const START: &str = "start"; +const COMPLETE: &str = "complete"; +const UNKNOWN: &str = "unknown"; +const UNSPECIFIED: &str = "unspecified"; +const ASSIGN: &str = "assign"; +const ATE_ABORT: &str = "ate_abort"; +const AUTOSKIP: &str = "autoskip"; +const MANUAL_SKIP: &str = "manualskip"; +const PI_ABORT: &str = "pi_abort"; +const RE_ASSIGN: &str = "reassign"; +const RESUME: &str = "resume"; +const SUSPEND: &str = "suspend"; +const WITHDRAW: &str = "withdraw"; static STRINGS_TO_LIFECYCLE: Lazy> = Lazy::new(|| { HashMap::from_iter(vec![ @@ -59,7 +59,7 @@ static LIFECYCLE_TO_STRINGS: Lazy> = impl Display for XesStandardLifecycle { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", LIFECYCLE_TO_STRINGS.get(&self).unwrap().to_string()) + write!(f, "{}", LIFECYCLE_TO_STRINGS.get(self).unwrap()) } } diff --git a/Ficus/src/rust/ficus/src/event_log/core/event/lifecycle/xes_lifecycle.rs b/Ficus/src/rust/ficus/src/event_log/core/event/lifecycle/xes_lifecycle.rs index 26a627ed8..458b0ccc6 100644 --- a/Ficus/src/rust/ficus/src/event_log/core/event/lifecycle/xes_lifecycle.rs +++ b/Ficus/src/rust/ficus/src/event_log/core/event/lifecycle/xes_lifecycle.rs @@ -1,5 +1,5 @@ use super::{braf_lifecycle::XesBrafLifecycle, standard_lifecycle::XesStandardLifecycle}; -use std::str::FromStr; +use std::{fmt::Display, str::FromStr}; #[derive(Debug, Clone, Copy, PartialEq)] pub enum Lifecycle { @@ -7,12 +7,15 @@ pub enum Lifecycle { BrafLifecycle(XesBrafLifecycle), } -impl ToString for Lifecycle { - fn to_string(&self) -> String { - match self { - Self::XesStandardLifecycle(xes_lifecycle) => xes_lifecycle.to_string(), - Self::BrafLifecycle(braf_lifecycle) => braf_lifecycle.to_string(), - } +impl Display for Lifecycle { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str( + match self { + Self::XesStandardLifecycle(xes_lifecycle) => xes_lifecycle.to_string(), + Self::BrafLifecycle(braf_lifecycle) => braf_lifecycle.to_string(), + } + .as_str(), + ) } } diff --git a/Ficus/src/rust/ficus/src/event_log/core/log_iterator.rs b/Ficus/src/rust/ficus/src/event_log/core/log_iterator.rs index b808b6723..e9421cd79 100644 --- a/Ficus/src/rust/ficus/src/event_log/core/log_iterator.rs +++ b/Ficus/src/rust/ficus/src/event_log/core/log_iterator.rs @@ -76,7 +76,7 @@ where if self.event_index >= events.len() { None } else { - let item = (&self.event_processor)(&events[self.event_index].borrow()); + let item = (self.event_processor)(&events[self.event_index].borrow()); self.event_index += 1; Some(item) diff --git a/Ficus/src/rust/ficus/src/event_log/core/trace/trace.rs b/Ficus/src/rust/ficus/src/event_log/core/trace/trace.rs index bd82d5ba1..813a999ea 100644 --- a/Ficus/src/rust/ficus/src/event_log/core/trace/trace.rs +++ b/Ficus/src/rust/ficus/src/event_log/core/trace/trace.rs @@ -36,5 +36,5 @@ pub trait TraceInfo { } pub trait TraceEventsPositions { - fn event_positions(&self, event_class: &String) -> Option<&Vec>; + fn event_positions(&self, event_class: &str) -> Option<&Vec>; } diff --git a/Ficus/src/rust/ficus/src/event_log/core/trace/traces_holder.rs b/Ficus/src/rust/ficus/src/event_log/core/trace/traces_holder.rs index 4dabfd56b..238dd57ad 100644 --- a/Ficus/src/rust/ficus/src/event_log/core/trace/traces_holder.rs +++ b/Ficus/src/rust/ficus/src/event_log/core/trace/traces_holder.rs @@ -22,10 +22,7 @@ where { fn clone(&self) -> Self { Self { - traces: (&self.traces) - .into_iter() - .map(|ptr| Rc::new(RefCell::new(ptr.borrow().clone()))) - .collect(), + traces: self.traces.iter().map(|ptr| Rc::new(RefCell::new(ptr.borrow().clone()))).collect(), user_data: self.user_data.clone(), } @@ -39,14 +36,14 @@ where pub fn empty() -> Self { Self { traces: vec![], - user_data: UserDataImpl::new(), + user_data: Default::default(), } } pub fn new(traces: Vec>>) -> Self { Self { traces, - user_data: UserDataImpl::new(), + user_data: Default::default(), } } diff --git a/Ficus/src/rust/ficus/src/event_log/xes/reader/file_xes_log_reader.rs b/Ficus/src/rust/ficus/src/event_log/xes/reader/file_xes_log_reader.rs index 9b2e4a305..a788bba3a 100644 --- a/Ficus/src/rust/ficus/src/event_log/xes/reader/file_xes_log_reader.rs +++ b/Ficus/src/rust/ficus/src/event_log/xes/reader/file_xes_log_reader.rs @@ -6,7 +6,7 @@ use std::{ rc::Rc, }; -use quick_xml::{events::BytesStart, Reader}; +use quick_xml::{Reader, events::BytesStart}; use crate::event_log::{ core::event::event::EventPayloadValue, @@ -174,14 +174,8 @@ impl<'a> FromFileXesEventLogReader<'a> { fn try_read_tag(tag: &BytesStart) -> Option> { let result = match tag.name().as_ref() { - EXTENSION_TAG_NAME => match Self::try_read_extension(&tag) { - Some(extension) => Some(XesEventLogItem::Extension(extension)), - None => None, - }, - CLASSIFIER_TAG_NAME => match Self::try_read_classifier(&tag) { - Some(classifier) => Some(XesEventLogItem::Classifier(classifier)), - None => None, - }, + EXTENSION_TAG_NAME => Self::try_read_extension(tag).map(XesEventLogItem::Extension), + CLASSIFIER_TAG_NAME => Self::try_read_classifier(tag).map(XesEventLogItem::Classifier), _ => None, }; @@ -195,14 +189,12 @@ impl<'a> FromFileXesEventLogReader<'a> { fn try_read_property(tag: &BytesStart) -> Option> { match utils::read_payload_like_tag(tag) { Some(descriptor) => { - let payload_type = descriptor.payload_type.as_str().as_bytes(); + let payload_type = descriptor.payload_type.as_bytes(); let key = descriptor.key; let value = descriptor.value.as_str(); - match utils::extract_payload_value(payload_type, key.as_str(), value) { - Some(value) => Some(XesEventLogItem::Property(XesProperty { name: key, value })), - None => None, - } + utils::extract_payload_value(payload_type, key.as_str(), value) + .map(|value| XesEventLogItem::Property(XesProperty { name: key, value })) } None => None, } @@ -216,11 +208,11 @@ impl<'a> FromFileXesEventLogReader<'a> { Err(_) => return None, Ok(quick_xml::events::Event::Empty(tag)) => { if let Some(descriptor) = utils::read_payload_like_tag(&tag) { - if let None = map { + if map.is_none() { map = Some(HashMap::new()) } - let payload_type = descriptor.payload_type.as_str().as_bytes(); + let payload_type = descriptor.payload_type.as_bytes(); let value = utils::extract_payload_value(payload_type, descriptor.key.as_str(), &descriptor.value); if let Some(payload_value) = value { map.as_mut().unwrap().insert(descriptor.key, payload_value); @@ -299,7 +291,7 @@ impl<'a> FromFileXesEventLogReader<'a> { } } - if !name.is_some() || !prefix.is_some() || !uri.is_some() { + if name.is_none() || prefix.is_none() || uri.is_none() { return None; } diff --git a/Ficus/src/rust/ficus/src/event_log/xes/reader/utils.rs b/Ficus/src/rust/ficus/src/event_log/xes/reader/utils.rs index d61186634..617c3fd0d 100644 --- a/Ficus/src/rust/ficus/src/event_log/xes/reader/utils.rs +++ b/Ficus/src/rust/ficus/src/event_log/xes/reader/utils.rs @@ -7,7 +7,7 @@ use crate::event_log::{core::event::event::EventPayloadValue, xes::constants::*} use crate::event_log::core::event::lifecycle::xes_lifecycle::Lifecycle; use quick_xml::{ escape::unescape, - events::{attributes::Attribute, BytesStart}, + events::{BytesStart, attributes::Attribute}, }; pub struct KeyValuePair { @@ -22,8 +22,8 @@ pub struct PayloadTagDescriptor { } pub fn read_payload_like_tag(tag: &BytesStart) -> Option { - let kv = extract_key_value(&tag); - if !kv.value.is_some() || !kv.key.is_some() { + let kv = extract_key_value(tag); + if kv.value.is_none() || kv.key.is_none() { return None; } @@ -48,11 +48,11 @@ pub fn extract_key_value(start: &BytesStart) -> KeyValuePair { match attr { Err(_) => continue, Ok(real_attr) => match real_attr.key.0 { - KEY_ATTR_NAME => match String::from_utf8(real_attr.value.to_owned().to_vec()) { + KEY_ATTR_NAME => match String::from_utf8(real_attr.value.to_vec()) { Err(_) => continue, Ok(string) => key = Some(string), }, - VALUE_ATTR_NAME => match String::from_utf8(real_attr.value.to_owned().to_vec()) { + VALUE_ATTR_NAME => match String::from_utf8(real_attr.value.to_vec()) { Err(_) => continue, Ok(string) => value = Some(string), }, @@ -61,7 +61,7 @@ pub fn extract_key_value(start: &BytesStart) -> KeyValuePair { } } - return KeyValuePair { key, value }; + KeyValuePair { key, value } } #[inline] diff --git a/Ficus/src/rust/ficus/src/event_log/xes/reader/xes_log_trace_reader.rs b/Ficus/src/rust/ficus/src/event_log/xes/reader/xes_log_trace_reader.rs index d4fd7d0c4..7db482d12 100644 --- a/Ficus/src/rust/ficus/src/event_log/xes/reader/xes_log_trace_reader.rs +++ b/Ficus/src/rust/ficus/src/event_log/xes/reader/xes_log_trace_reader.rs @@ -64,12 +64,8 @@ impl<'a> TraceXesEventLogIterator<'a> { match self.reader.borrow_mut().read_event_into(&mut self.buffer) { Ok(quick_xml::events::Event::End(end)) => match end.name().0 { EVENT_TAG_NAME => { - if !name.is_some() { - return None; - } - if !date.is_some() { - return None; - } + name.as_ref()?; + date?; let event = XesEventImpl::new_all_fields(name.unwrap(), date.unwrap(), Some(payload)); return Some(event); @@ -78,7 +74,7 @@ impl<'a> TraceXesEventLogIterator<'a> { }, Ok(quick_xml::events::Event::Empty(empty)) => match utils::read_payload_like_tag(&empty) { Some(descriptor) => { - let payload_type = descriptor.payload_type.as_str().as_bytes(); + let payload_type = descriptor.payload_type.as_bytes(); let key = descriptor.key.as_str(); let value = descriptor.value.as_str(); @@ -117,16 +113,15 @@ impl<'a> TraceXesEventLogIterator<'a> { globals: &HashMap>, ) -> bool { let payload_value = utils::extract_payload_value(payload_type, key, value); - if !payload_value.is_some() { + if payload_value.is_none() { return false; } - if let Some(event_globals) = globals.get(EVENT_TAG_NAME_STR) { - if let Some(default_value) = event_globals.get(key) { - if default_value == payload_value.as_ref().unwrap() { - return false; - } - } + if let Some(event_globals) = globals.get(EVENT_TAG_NAME_STR) + && let Some(default_value) = event_globals.get(key) + && default_value == payload_value.as_ref().unwrap() + { + return false; } Self::update_event_data(key, payload_value.unwrap(), date, name, payload); diff --git a/Ficus/src/rust/ficus/src/event_log/xes/writer/xes_event_log_writer.rs b/Ficus/src/rust/ficus/src/event_log/xes/writer/xes_event_log_writer.rs index 402a1d700..40d52e393 100644 --- a/Ficus/src/rust/ficus/src/event_log/xes/writer/xes_event_log_writer.rs +++ b/Ficus/src/rust/ficus/src/event_log/xes/writer/xes_event_log_writer.rs @@ -10,7 +10,7 @@ use crate::{ }, xes::{constants::*, xes_event_log::XesEventLogImpl}, }, - utils::xml_utils::{write_empty, StartEndElementCookie, XmlWriteError}, + utils::xml_utils::{StartEndElementCookie, XmlWriteError, write_empty}, }; pub fn write_xes_log_to_bytes(log: &XesEventLogImpl) -> Result, XmlWriteError> { @@ -40,7 +40,7 @@ pub fn serialize_event_log(log: &XesEventLogImpl) -> Result(log: &XesEventLogImpl, writer: &RefCell>) -> Result<(), XmlWriteError> { - let _log_cookie = StartEndElementCookie::new(&writer, LOG_TAG_NAME_STR); + let _log_cookie = StartEndElementCookie::new(writer, LOG_TAG_NAME_STR); for ext in log.extensions() { let attrs = vec![ @@ -60,31 +60,31 @@ fn write_event_log_to_writer(log: &XesEventLogImpl, writer: & } for (name, value) in log.ordered_properties() { - write_payload_tag(&writer, name, value)?; + write_payload_tag(writer, name, value)?; } for (scope, defaults) in log.ordered_globals() { let mut attrs = vec![(SCOPE_ATTR_NAME_STR, scope.as_str())]; - let _global_cookie = StartEndElementCookie::new_with_attrs(&writer, GLOBAL_TAG_NAME_STR, &attrs); + let _global_cookie = StartEndElementCookie::new_with_attrs(writer, GLOBAL_TAG_NAME_STR, &attrs); for (key, value) in defaults { attrs.clear(); - write_payload_tag(&writer, key, value)?; + write_payload_tag(writer, key, value)?; } } for trace in log.traces() { let trace = trace.borrow(); let events = trace.events(); - if events.len() == 0 { + if events.is_empty() { continue; } - let _trace_cookie = StartEndElementCookie::new(&writer, TRACE_TAG_NAME_STR); + let _trace_cookie = StartEndElementCookie::new(writer, TRACE_TAG_NAME_STR); for event in events { - let _event_cookie = StartEndElementCookie::new(&writer, EVENT_TAG_NAME_STR); + let _event_cookie = StartEndElementCookie::new(writer, EVENT_TAG_NAME_STR); let event = event.borrow(); let attrs = vec![(KEY_ATTR_NAME_STR, CONCEPT_NAME_STR), (VALUE_ATTR_NAME_STR, event.name())]; @@ -97,7 +97,7 @@ fn write_event_log_to_writer(log: &XesEventLogImpl, writer: & write_empty(&mut writer.borrow_mut(), DATE_TAG_NAME_STR, &attrs)?; for (key, value) in event.ordered_payload() { - write_payload_tag(&writer, key, value)?; + write_payload_tag(writer, key, value)?; } } } diff --git a/Ficus/src/rust/ficus/src/event_log/xes/xes_event_log.rs b/Ficus/src/rust/ficus/src/event_log/xes/xes_event_log.rs index af655f8bb..c7bc5d314 100644 --- a/Ficus/src/rust/ficus/src/event_log/xes/xes_event_log.rs +++ b/Ficus/src/rust/ficus/src/event_log/xes/xes_event_log.rs @@ -106,7 +106,7 @@ impl XesEventLogImpl { XesEventLogItem::Global(global) => _ = globals.insert(global.scope, global.default_values), XesEventLogItem::Extension(extension) => extensions.push(extension), XesEventLogItem::Classifier(classifier) => classifiers.push(classifier), - XesEventLogItem::Property(property) => _ = properties.push(property), + XesEventLogItem::Property(property) => properties.push(property), } } @@ -160,7 +160,7 @@ impl EventLog for XesEventLogImpl { } fn traces(&self) -> &Vec>> { - &self.base.get_traces() + self.base.get_traces() } fn push(&mut self, trace: Rc>) { diff --git a/Ficus/src/rust/ficus/src/event_log/xes/xes_trace.rs b/Ficus/src/rust/ficus/src/event_log/xes/xes_trace.rs index c5e6278c3..ef9670987 100644 --- a/Ficus/src/rust/ficus/src/event_log/xes/xes_trace.rs +++ b/Ficus/src/rust/ficus/src/event_log/xes/xes_trace.rs @@ -52,7 +52,7 @@ impl Trace for XesTraceImpl { } fn events(&self) -> &Vec>> { - &self.events_holder.events() + self.events_holder.events() } fn events_mut(&mut self) -> &mut Vec>> { diff --git a/Ficus/src/rust/ficus/src/features/analysis/directly_follows_graph.rs b/Ficus/src/rust/ficus/src/features/analysis/directly_follows_graph.rs index de35cc8de..b34e7922d 100644 --- a/Ficus/src/rust/ficus/src/features/analysis/directly_follows_graph.rs +++ b/Ficus/src/rust/ficus/src/features/analysis/directly_follows_graph.rs @@ -63,10 +63,7 @@ pub fn construct_dfg_by_attribute(log: &XesEventLogImpl, attribute: &str) -> Def let attribute_value = match event.payload_map() { None => None, - Some(map) => match map.get(attribute) { - None => None, - Some(value) => Some(value.to_string_repr().to_owned()), - }, + Some(map) => map.get(attribute).map(|value| value.to_string_repr().to_owned()), }; let event_name_boxed = HeapedOrOwned::Heaped(event.name_pointer().clone()); diff --git a/Ficus/src/rust/ficus/src/features/analysis/entropy/dfg_entropy.rs b/Ficus/src/rust/ficus/src/features/analysis/entropy/dfg_entropy.rs index 1738cd168..3dedd8318 100644 --- a/Ficus/src/rust/ficus/src/features/analysis/entropy/dfg_entropy.rs +++ b/Ficus/src/rust/ficus/src/features/analysis/entropy/dfg_entropy.rs @@ -16,7 +16,7 @@ where TLog: EventLog, { let dfr_or_dpr_calculator = |pair_count, events_count, event_count| { - let alpha = 1 as f64 / event_count as f64; + let alpha = 1_f64 / event_count as f64; let x = alpha + pair_count as f64; let y = alpha * ((events_count + 1) as f64) + event_count as f64; x / y diff --git a/Ficus/src/rust/ficus/src/features/analysis/entropy/pos_entropy.rs b/Ficus/src/rust/ficus/src/features/analysis/entropy/pos_entropy.rs index d509eca9d..6af7610c5 100644 --- a/Ficus/src/rust/ficus/src/features/analysis/entropy/pos_entropy.rs +++ b/Ficus/src/rust/ficus/src/features/analysis/entropy/pos_entropy.rs @@ -11,7 +11,7 @@ where calculate_entropies(log, ignored_events.as_ref(), calculate_pos_entropy_for_event) } -pub fn calculate_pos_entropy_for_event(log: &TLog, event_name: &String, ignored_events: Option<&HashSet>) -> f64 +pub fn calculate_pos_entropy_for_event(log: &TLog, event_name: &str, ignored_events: Option<&HashSet>) -> f64 where TLog: EventLog, { @@ -26,10 +26,10 @@ where let event = event.borrow(); let name = event.name(); - if let Some(ignored_events_set) = ignored_events { - if ignored_events_set.contains(name) { - continue; - } + if let Some(ignored_events_set) = ignored_events + && ignored_events_set.contains(name) + { + continue; } empty_trace = false; diff --git a/Ficus/src/rust/ficus/src/features/analysis/entropy/pos_entropy_fast.rs b/Ficus/src/rust/ficus/src/features/analysis/entropy/pos_entropy_fast.rs index 4d3a58f95..fc66c997f 100644 --- a/Ficus/src/rust/ficus/src/features/analysis/entropy/pos_entropy_fast.rs +++ b/Ficus/src/rust/ficus/src/features/analysis/entropy/pos_entropy_fast.rs @@ -14,7 +14,7 @@ where calculate_entropies(log, ignored_events, calculate_pos_entropy_for_event_fast) } -pub fn calculate_pos_entropy_for_event_fast(log: &TLog, name: &String, ignored_events: Option<&HashSet>) -> f64 +pub fn calculate_pos_entropy_for_event_fast(log: &TLog, name: &str, ignored_events: Option<&HashSet>) -> f64 where TLog: EventLog, { diff --git a/Ficus/src/rust/ficus/src/features/analysis/entropy/shared.rs b/Ficus/src/rust/ficus/src/features/analysis/entropy/shared.rs index 3c4f49543..92d0246ff 100644 --- a/Ficus/src/rust/ficus/src/features/analysis/entropy/shared.rs +++ b/Ficus/src/rust/ficus/src/features/analysis/entropy/shared.rs @@ -47,12 +47,12 @@ fn calculate_vector_length(log: &TLog) -> usize where TLog: EventLog, { - log.traces().into_iter().map(|trace| trace.borrow().events().len()).max().unwrap() + log.traces().iter().map(|trace| trace.borrow().events().len()).max().unwrap() } -pub fn calculate_pos_entropy(probabilities: &mut Vec, traces_count: f64) -> f64 { - for i in 0..probabilities.len() { - probabilities[i] = probabilities[i] / traces_count; +pub fn calculate_pos_entropy(probabilities: &mut [f64], traces_count: f64) -> f64 { + for p in probabilities.iter_mut() { + *p /= traces_count; } let log = traces_count.log2(); @@ -81,18 +81,18 @@ pub fn calculate_entropies( ) -> HashMap where TLog: EventLog, - TEntropyCalculator: Fn(&TLog, &String, Option<&HashSet>) -> f64, + TEntropyCalculator: Fn(&TLog, &str, Option<&HashSet>) -> f64, { let log_info = OfflineEventLogInfo::create_from(EventLogInfoCreationDto::default(log)); let mut entropies = HashMap::new(); for event_name in log_info.all_event_classes() { - if let Some(ignored_events) = ignored_events { - if ignored_events.contains(event_name.as_str()) { - continue; - } + if let Some(ignored_events) = ignored_events + && ignored_events.contains(event_name.as_str()) + { + continue; } - let entropy = entropy_calculator(log, &event_name, ignored_events); + let entropy = entropy_calculator(log, event_name, ignored_events); entropies.insert(event_name.to_owned(), entropy); } diff --git a/Ficus/src/rust/ficus/src/features/analysis/log_info/dfg_info.rs b/Ficus/src/rust/ficus/src/features/analysis/log_info/dfg_info.rs index 5fd017fa8..1614c9f19 100644 --- a/Ficus/src/rust/ficus/src/features/analysis/log_info/dfg_info.rs +++ b/Ficus/src/rust/ficus/src/features/analysis/log_info/dfg_info.rs @@ -1,11 +1,11 @@ use std::collections::{HashMap, HashSet}; pub trait DfgInfo { - fn get_directly_follows_count(&self, first: &String, second: &String) -> usize; + fn get_directly_follows_count(&self, first: &str, second: &str) -> usize; fn is_in_directly_follows_relation(&self, left: &str, right: &str) -> bool; - fn get_followed_events(&self, event_class: &String) -> Option<&HashMap>; - fn get_precedes_events(&self, event_class: &String) -> Option<&HashMap>; - fn is_event_with_single_follower(&self, event_class: &String) -> bool; + fn get_followed_events(&self, event_class: &str) -> Option<&HashMap>; + fn get_precedes_events(&self, event_class: &str) -> Option<&HashMap>; + fn is_event_with_single_follower(&self, event_class: &str) -> bool; } #[derive(Debug)] @@ -48,11 +48,11 @@ impl OfflineDfgInfo { } impl DfgInfo for OfflineDfgInfo { - fn get_directly_follows_count(&self, first: &String, second: &String) -> usize { - if let Some(values) = self.followed_events.get(first) { - if let Some(dfg_count) = values.get(second) { - return *dfg_count; - } + fn get_directly_follows_count(&self, first: &str, second: &str) -> usize { + if let Some(values) = self.followed_events.get(first) + && let Some(dfg_count) = values.get(second) + { + return *dfg_count; } 0 @@ -66,21 +66,21 @@ impl DfgInfo for OfflineDfgInfo { } } - fn get_followed_events(&self, event_class: &String) -> Option<&HashMap> { + fn get_followed_events(&self, event_class: &str) -> Option<&HashMap> { match self.followed_events.get(event_class) { Some(followers_counts) => Some(followers_counts), None => None, } } - fn get_precedes_events(&self, event_class: &String) -> Option<&HashMap> { + fn get_precedes_events(&self, event_class: &str) -> Option<&HashMap> { match self.precedes_events.get(event_class) { Some(followers_counts) => Some(followers_counts), None => None, } } - fn is_event_with_single_follower(&self, event_class: &String) -> bool { + fn is_event_with_single_follower(&self, event_class: &str) -> bool { self.events_with_single_follower.contains(event_class) } } diff --git a/Ficus/src/rust/ficus/src/features/analysis/log_info/event_log_info.rs b/Ficus/src/rust/ficus/src/features/analysis/log_info/event_log_info.rs index b9cdfc653..456fc3b82 100644 --- a/Ficus/src/rust/ficus/src/features/analysis/log_info/event_log_info.rs +++ b/Ficus/src/rust/ficus/src/features/analysis/log_info/event_log_info.rs @@ -42,7 +42,7 @@ impl EventLogCounts for EventLogCountsImpl { pub trait EventLogInfo { fn counts(&self) -> Option<&dyn EventLogCounts>; fn event_classes_count(&self) -> u64; - fn event_count(&self, event_class: &String) -> u64; + fn event_count(&self, event_class: &str) -> u64; fn dfg_info(&self) -> &dyn DfgInfo; fn all_event_classes(&self) -> Vec<&String>; fn start_event_classes(&self) -> &HashSet; @@ -65,7 +65,7 @@ impl OfflineEventLogInfo { .keys() .filter(|c| match dfg_info.precedes_events.get(*c) { None => true, - Some(precedes) => precedes.len() == 0, + Some(precedes) => precedes.is_empty(), }) .map(|c| c.to_owned()) .collect(); @@ -74,7 +74,7 @@ impl OfflineEventLogInfo { .keys() .filter(|c| match dfg_info.followed_events.get(*c) { None => true, - Some(followers) => followers.len() == 0, + Some(followers) => followers.is_empty(), }) .map(|c| c.to_owned()) .collect(); @@ -131,7 +131,7 @@ impl OfflineEventLogInfo { events_count += events.len(); let mut prev_event_name = None; - if events.len() > 0 { + if !events.is_empty() { start_event_classes.insert(events.first().unwrap().borrow().name().to_owned()); end_event_classes.insert(events.last().unwrap().borrow().name().to_owned()); } @@ -140,10 +140,10 @@ impl OfflineEventLogInfo { let event = event.borrow(); let current_name = event.name().to_owned(); - if let Some(ignored_events) = ignored_events { - if ignored_events.contains(¤t_name) { - continue; - } + if let Some(ignored_events) = ignored_events + && ignored_events.contains(¤t_name) + { + continue; } update_events_counts(¤t_name); @@ -162,8 +162,8 @@ impl OfflineEventLogInfo { prev_event_name = Some(event.name().to_owned()); } - if add_fake_start_end_events && prev_event_name.is_some() { - update_pairs_count(&prev_event_name.unwrap(), &FAKE_EVENT_END_NAME.to_string()); + if add_fake_start_end_events && let Some(prev_event_name) = prev_event_name { + update_pairs_count(&prev_event_name, &FAKE_EVENT_END_NAME.to_string()); } } @@ -241,7 +241,7 @@ impl EventLogInfo for OfflineEventLogInfo { self.event_classes_counts.len() as u64 } - fn event_count(&self, event_class: &String) -> u64 { + fn event_count(&self, event_class: &str) -> u64 { match self.event_classes_counts.get(event_class) { Some(value) => value.to_owned(), None => 0, @@ -253,7 +253,7 @@ impl EventLogInfo for OfflineEventLogInfo { } fn all_event_classes(&self) -> Vec<&String> { - self.event_classes_counts.keys().into_iter().collect() + self.event_classes_counts.keys().collect() } fn start_event_classes(&self) -> &HashSet { diff --git a/Ficus/src/rust/ficus/src/features/analysis/patterns/activity_instances.rs b/Ficus/src/rust/ficus/src/features/analysis/patterns/activity_instances.rs index f65db70f4..786db9cda 100644 --- a/Ficus/src/rust/ficus/src/features/analysis/patterns/activity_instances.rs +++ b/Ficus/src/rust/ficus/src/features/analysis/patterns/activity_instances.rs @@ -97,13 +97,10 @@ pub fn extract_activities_instances_strict( let mut suitable_activities = get_all_child_activities(activities) .into_iter() - .filter_map(|a| match a.borrow().repeat_set() { - None => None, - Some(_) => Some(a.clone()), - }) + .filter_map(|a| a.borrow().repeat_set().as_ref().map(|_| a.clone())) .collect::>>>(); - suitable_activities.sort_by(|f, s| s.borrow().repeat_set().unwrap().len().cmp(&f.borrow().repeat_set().unwrap().len())); + suitable_activities.sort_by_key(|a| std::cmp::Reverse(a.borrow().repeat_set().unwrap().len())); for trace in log { let mut index = 0; @@ -153,10 +150,10 @@ pub fn extract_activities_instances_strict( result } -fn get_all_child_activities(activities: &Vec>>) -> Vec>> { +fn get_all_child_activities(activities: &[Rc>]) -> Vec>> { let mut result = vec![]; - let mut queue = VecDeque::from_iter(activities.iter().map(|a| a.clone())); + let mut queue = VecDeque::from_iter(activities.iter().cloned()); while !queue.is_empty() { let current = queue.pop_front().unwrap(); @@ -172,7 +169,7 @@ fn get_all_child_activities(activities: &Vec>>) -> Vec< pub fn extract_activities_instances( log: &Vec>, - activities: &mut Vec>>, + activities: &mut [Rc>], narrow_kind: &ActivityNarrowingKind, min_events_in_activity: usize, filtering_kind: &ActivityInTraceFilterKind, @@ -188,10 +185,10 @@ pub fn extract_activities_instances( let mut current_event_classes = HashSet::new(); while index.is_none() || index.unwrap() < trace.len() { - if index.is_none() { - index = Some(0); + if let Some(index) = &mut index { + *index += 1; } else { - *index.as_mut().unwrap() += 1; + index = Some(0); } if index.unwrap() >= trace.len() { @@ -227,12 +224,12 @@ pub fn extract_activities_instances( let mut found_new_set = false; for activities_set in activities_by_size.iter() { - if activities_set.len() == 0 || activities_set[0].borrow().len() < current_activity.as_ref().unwrap().borrow().len() { + if activities_set.is_empty() || activities_set[0].borrow().len() < current_activity.as_ref().unwrap().borrow().len() { continue; } for activity in activities_set { - if new_set.is_subset(&activity.borrow().event_classes()) { + if new_set.is_subset(activity.borrow().event_classes()) { current_activity = Some(Rc::clone(activity)); found_new_set = true; break; @@ -270,14 +267,14 @@ pub fn extract_activities_instances( } } - if last_activity_start_index.is_some() { + if let Some(last_activity_start_index) = last_activity_start_index { let activity = narrow_activity(current_activity.as_ref().unwrap(), ¤t_event_classes, narrow_kind); current_activity = Some(activity); let activity_instance = ActivityInTraceInfo { node: Rc::clone(current_activity.as_ref().unwrap()), - start_pos: last_activity_start_index.unwrap(), - length: index.unwrap() - last_activity_start_index.unwrap(), + start_pos: last_activity_start_index, + length: index.unwrap() - last_activity_start_index, }; if is_suitable_activity_instance(&activity_instance, min_events_in_activity, filtering_kind) { @@ -298,23 +295,21 @@ fn is_suitable_activity_instance( ) -> bool { if filtering_kind == &ActivityInTraceFilterKind::NoFilter { true + } else if instance.node.borrow().len() < min_events_in_activity { + false } else { - if instance.node.borrow().len() < min_events_in_activity { - false - } else { - instance.length > instance.node.borrow().len() / 2 - } + instance.length > instance.node.borrow().len() / 2 } } -fn split_activities_nodes_by_size(activities: &mut Vec>>) -> Vec>>> { +fn split_activities_nodes_by_size(activities: &mut [Rc>]) -> Vec>>> { if activities.is_empty() { return vec![]; } - activities.sort_by(|first, second| first.borrow().len().cmp(&second.borrow().len())); + activities.sort_by_key(|first| first.borrow().len()); let mut current_length = activities[0].borrow().len(); - let mut result = vec![vec![Rc::clone(activities.get(0).unwrap())]]; + let mut result = vec![vec![Rc::clone(activities.first().unwrap())]]; for activity in activities.iter() { if activity.borrow().len() != current_length { @@ -329,7 +324,7 @@ fn split_activities_nodes_by_size(activities: &mut Vec> result .get_mut(i) .unwrap() - .sort_by(|first, second| first.borrow().name().cmp(&second.borrow().name())); + .sort_by(|first, second| first.borrow().name().cmp(second.borrow().name())); } result @@ -355,7 +350,7 @@ fn narrow_activity( let current_activity_ptr = q.pop_front().unwrap(); let current_activity = current_activity_ptr.borrow(); - if current_activity.event_classes().is_superset(&activities_set) { + if current_activity.event_classes().is_superset(activities_set) { result.push(Rc::clone(¤t_activity_ptr)); for child_node in current_activity.children() { q.push_back(Rc::clone(child_node)); @@ -364,7 +359,7 @@ fn narrow_activity( } if result.is_empty() { - return Rc::clone(&node_ptr); + return Rc::clone(node_ptr); } let result = result.iter(); @@ -383,8 +378,8 @@ pub fn process_activities_in_trace (), - TActivityHandleFunc: FnMut(&ActivityInTraceInfo) -> (), + TUndefActivityHandleFunc: FnMut(usize, usize), + TActivityHandleFunc: FnMut(&ActivityInTraceInfo), { let mut index = 0; for instance in activities_instances { @@ -449,15 +444,15 @@ impl UnderlyingEventsInfo { } } -const HIERARCHY_LEVEL: &'static str = "HIERARCHY_LEVEL"; -const UNDERLYING_EVENTS: &'static str = "UNDERLYING_EVENTS"; +const HIERARCHY_LEVEL: &str = "HIERARCHY_LEVEL"; +const UNDERLYING_EVENTS: &str = "UNDERLYING_EVENTS"; context_key! { HIERARCHY_LEVEL, usize } context_key! { UNDERLYING_EVENTS, UnderlyingEventsInfo } pub fn create_new_log_from_activities_instances( log: &XesEventLogImpl, - instances: &Vec>, + instances: &[Vec], strategy: &UndefActivityHandlingStrategy, event_from_activity_factory: &TEventFactory, ) -> XesEventLogImpl @@ -512,12 +507,7 @@ where let base_pattern = if let Some(repeat_set) = activity.node.borrow().repeat_set() { let trace = log.traces().get(repeat_set.trace_index).unwrap(); let sub_array = repeat_set.sub_array; - Some( - trace.borrow().events()[sub_array.start_index..sub_array.start_index + sub_array.length] - .iter() - .map(|e| e.clone()) - .collect(), - ) + Some(trace.borrow().events()[sub_array.start_index..sub_array.start_index + sub_array.length].to_vec()) } else { None }; @@ -527,7 +517,7 @@ where user_data.put_concrete(UNDERLYING_EVENTS_KEY.key(), info); }; - process_activities_in_trace(trace.events().len(), &instances, undef_activity_func, activity_func); + process_activities_in_trace(trace.events().len(), instances, undef_activity_func, activity_func); new_log.push(new_trace_ptr) } @@ -538,8 +528,8 @@ where pub fn add_unattached_activities( log: &Vec>, - activities: &mut Vec>>, - existing_instances: &Vec>, + activities: &mut [Rc>], + existing_instances: &[Vec], min_numbers_of_events: usize, should_narrow: &ActivityNarrowingKind, min_events_in_activity: usize, @@ -578,7 +568,7 @@ pub fn add_unattached_activities( let length = trace.len(); process_activities_in_trace(length, trace_activities, handle_unattached_events, |_| {}); - new_trace_activities.extend(trace_activities.iter().map(|instance| instance.clone())); + new_trace_activities.extend(trace_activities.iter().cloned()); new_trace_activities.sort_by(|first, second| first.start_pos.cmp(&second.start_pos)); new_activities.push(new_trace_activities); @@ -612,7 +602,7 @@ fn create_activities_logs_from_log(log: &XesEventLogImpl) -> HashMap HashMap( log: &TLog, - activities: &Vec>, + activities: &[Vec], activity_level: usize, ) -> HashMap>> { let mut activities_to_logs: HashMap>> = HashMap::new(); @@ -654,8 +644,8 @@ fn create_log_from_traces_activities( let trace = trace.borrow(); let events = trace.events(); - for i in start..end { - new_trace.push(Rc::new(RefCell::new(events[i].borrow().clone()))); + for event in events.iter().take(end).skip(start) { + new_trace.push(Rc::new(RefCell::new(event.borrow().clone()))); } let name = activity_info.node.borrow().name().as_ref().as_ref().to_owned(); @@ -687,16 +677,14 @@ where let trace = log.traces().get(sub_array.trace_index).unwrap().borrow(); let events = trace.events(); - let regex = match class_extractor { - Some(extractor) => Some(Regex::new(&extractor).unwrap()), - None => None, - }; + let regex = class_extractor.map(|extractor| Regex::new(extractor).unwrap()); - for index in left..right { + for (index, event) in events.iter().enumerate().take(right).skip(left) { name.push('('); - let event_name = events[index].borrow(); - let event_name = event_name.name(); + let event = event.borrow(); + let event_name = event.name(); + let event_name = match regex.as_ref() { Some(regex) => match regex.find(event_name) { Ok(Some(m)) => { @@ -711,7 +699,7 @@ where None => event_name, }; - name.push_str(&event_name); + name.push_str(event_name); name.push(')'); if index != right - 1 { @@ -737,7 +725,7 @@ pub fn count_underlying_events(log: &XesEventLogImpl) -> usize { } fn count_underlying_events_for_event(event: &mut XesEventImpl) -> usize { - if let Some(underlying_events) = event.user_data_mut().concrete_mut(&UNDERLYING_EVENTS_KEY.key()) { + if let Some(underlying_events) = event.user_data_mut().concrete_mut(UNDERLYING_EVENTS_KEY.key()) { let mut result = 0usize; for underlying_event in underlying_events.underlying_events() { result += count_underlying_events_for_event(underlying_event.borrow_mut().deref_mut()) @@ -755,7 +743,7 @@ where { let mut new_log = TLog::empty(); - for (trace, trace_activities) in log.traces().into_iter().zip(activities) { + for (trace, trace_activities) in log.traces().iter().zip(activities) { let trace = trace.borrow(); let mut new_trace = TLog::TTrace::empty(); @@ -785,7 +773,7 @@ pub fn execute_with_underlying_events(event: &Rc>, action: } pub fn substitute_underlying_events(event: &Rc>, trace: &mut XesTraceImpl) { - if let Some(underlying_events) = event.borrow_mut().user_data_mut().concrete(&UNDERLYING_EVENTS_KEY.key()) { + if let Some(underlying_events) = event.borrow_mut().user_data_mut().concrete(UNDERLYING_EVENTS_KEY.key()) { for underlying_event in underlying_events.underlying_events() { substitute_underlying_events(underlying_event, trace); } @@ -802,7 +790,7 @@ pub fn create_vector_of_underlying_events(event: &Rc>) -> } pub fn try_get_base_pattern(event: &Rc>) -> Option>>> { - if let Some(info) = event.borrow().user_data().concrete(&UNDERLYING_EVENTS_KEY.key()) { + if let Some(info) = event.borrow().user_data().concrete(UNDERLYING_EVENTS_KEY.key()) { info.base_pattern().cloned() } else { None @@ -810,7 +798,7 @@ pub fn try_get_base_pattern(event: &Rc>) -> Option>, result: &mut Vec>>) { - if let Some(underlying_events) = event.borrow_mut().user_data_mut().concrete(&UNDERLYING_EVENTS_KEY.key()) { + if let Some(underlying_events) = event.borrow_mut().user_data_mut().concrete(UNDERLYING_EVENTS_KEY.key()) { for underlying_event in underlying_events.underlying_events() { create_vector_of_underlying_events_intenral(underlying_event, result); } @@ -822,7 +810,7 @@ fn create_vector_of_underlying_events_intenral(event: &Rc> pub fn create_vector_of_immediate_underlying_events(event: &Rc>) -> Vec>> { let mut events = vec![]; - if let Some(underlying_events) = event.borrow_mut().user_data_mut().concrete(&UNDERLYING_EVENTS_KEY.key()) { + if let Some(underlying_events) = event.borrow_mut().user_data_mut().concrete(UNDERLYING_EVENTS_KEY.key()) { for underlying_event in underlying_events.underlying_events() { events.push(underlying_event.clone()); } diff --git a/Ficus/src/rust/ficus/src/features/analysis/patterns/contexts.rs b/Ficus/src/rust/ficus/src/features/analysis/patterns/contexts.rs index 07044478e..87c60e14b 100644 --- a/Ficus/src/rust/ficus/src/features/analysis/patterns/contexts.rs +++ b/Ficus/src/rust/ficus/src/features/analysis/patterns/contexts.rs @@ -64,7 +64,7 @@ where for trace in log.borrow().traces() { let mut processed_trace = vec![]; for event in trace.borrow().events() { - processed_trace.push((&class_extractor)(&event.borrow())); + processed_trace.push(class_extractor(&event.borrow())); } processed_log.push(processed_trace); diff --git a/Ficus/src/rust/ficus/src/features/analysis/patterns/entry_points.rs b/Ficus/src/rust/ficus/src/features/analysis/patterns/entry_points.rs index 1854e1e1e..c958d8270 100644 --- a/Ficus/src/rust/ficus/src/features/analysis/patterns/entry_points.rs +++ b/Ficus/src/rust/ficus/src/features/analysis/patterns/entry_points.rs @@ -1,11 +1,11 @@ use std::{cell::RefCell, collections::HashMap, rc::Rc}; use super::{ - activity_instances::{self, create_new_log_from_activities_instances, extract_activities_instances, ActivityInTraceInfo}, + activity_instances::{self, ActivityInTraceInfo, create_new_log_from_activities_instances, extract_activities_instances}, contexts::{ActivitiesDiscoveryContext, ActivitiesInstancesDiscoveryContext, PatternsDiscoveryContext}, - repeat_sets::{build_repeat_set_tree_from_repeats, build_repeat_sets, ActivityNode, SubArrayWithTraceIndex}, + repeat_sets::{ActivityNode, SubArrayWithTraceIndex, build_repeat_set_tree_from_repeats, build_repeat_sets}, repeats::{find_maximal_repeats, find_near_super_maximal_repeats, find_super_maximal_repeats}, - tandem_arrays::{find_maximal_tandem_arrays, find_primitive_tandem_arrays, SubArrayInTraceInfo}, + tandem_arrays::{SubArrayInTraceInfo, find_maximal_tandem_arrays, find_primitive_tandem_arrays}, }; use crate::{ event_log::{ @@ -13,7 +13,7 @@ use crate::{ xes::{xes_event::XesEventImpl, xes_event_log::XesEventLogImpl}, }, features::analysis::patterns::{ - activity_instances::{extract_activities_instances_strict, ActivitiesLogSource}, + activity_instances::{ActivitiesLogSource, extract_activities_instances_strict}, pattern_info::UnderlyingPatternKind, }, }; @@ -116,7 +116,7 @@ where TClassExtractor: Fn(&XesEventImpl) -> u64, TNameCreator: Fn(&SubArrayWithTraceIndex) -> String, { - let activity_instances = discover_activities_instances(&context); + let activity_instances = discover_activities_instances(context); activity_instances::create_logs_for_activities(&ActivitiesLogSource::TracesActivities( &context.patterns_context.log.borrow(), diff --git a/Ficus/src/rust/ficus/src/features/analysis/patterns/pattern_info.rs b/Ficus/src/rust/ficus/src/features/analysis/patterns/pattern_info.rs index 1506f828f..6d6de7264 100644 --- a/Ficus/src/rust/ficus/src/features/analysis/patterns/pattern_info.rs +++ b/Ficus/src/rust/ficus/src/features/analysis/patterns/pattern_info.rs @@ -5,7 +5,7 @@ use crate::{ use lazy_static::lazy_static; use std::{cell::RefCell, rc::Rc}; -const UNDERLYING_PATTERN_KIND: &'static str = "UNDERLYING_PATTERN_KIND"; +const UNDERLYING_PATTERN_KIND: &str = "UNDERLYING_PATTERN_KIND"; context_key! { UNDERLYING_PATTERN_KIND, UnderlyingPatternKind } @@ -69,15 +69,15 @@ impl UnderlyingPatternInfo { pub struct UnderlyingPatternGraphInfo { pattern_kind: UnderlyingPatternKind, base_pattern: Option>, - graph: Rc>, + graph: Box, } impl UnderlyingPatternGraphInfo { - pub fn new(pattern_kind: UnderlyingPatternKind, base_pattern: Option>, graph: Rc>) -> Self { + pub fn new(pattern_kind: UnderlyingPatternKind, base_pattern: Option>, graph: DefaultGraph) -> Self { Self { pattern_kind, base_pattern, - graph, + graph: Box::new(graph), } } @@ -89,7 +89,7 @@ impl UnderlyingPatternGraphInfo { self.base_pattern.as_ref() } - pub fn graph(&self) -> Rc> { - self.graph.clone() + pub fn graph(&self) -> &DefaultGraph { + self.graph.as_ref() } } diff --git a/Ficus/src/rust/ficus/src/features/analysis/patterns/repeat_sets.rs b/Ficus/src/rust/ficus/src/features/analysis/patterns/repeat_sets.rs index 5c3b1a592..fb19cf1e1 100644 --- a/Ficus/src/rust/ficus/src/features/analysis/patterns/repeat_sets.rs +++ b/Ficus/src/rust/ficus/src/features/analysis/patterns/repeat_sets.rs @@ -29,13 +29,12 @@ impl SubArrayWithTraceIndex { } } -pub fn build_repeat_sets(log: &Vec>, patterns: &Vec>) -> Vec { +pub fn build_repeat_sets(log: &[Vec], patterns: &[Vec]) -> Vec { let mut repeat_sets = HashMap::new(); let mut set = HashSet::new(); let mut vec: Vec = vec![]; - let mut trace_index = 0; - for (trace, trace_patterns) in log.into_iter().zip(patterns.iter()) { + for (trace_index, (trace, trace_patterns)) in log.iter().zip(patterns.iter()).enumerate() { for pattern in trace_patterns { let start = pattern.start_index; let end = start + pattern.length; @@ -51,16 +50,14 @@ pub fn build_repeat_sets(log: &Vec>, patterns: &Vec( - log: &Vec>, - repeats: &Vec, + log: &[Vec], + repeats: &[SubArrayWithTraceIndex], activity_level: usize, pattern_kind: UnderlyingPatternKind, name_creator: TNameCreator, @@ -138,7 +135,7 @@ pub fn build_repeat_set_tree_from_repeats( where TNameCreator: Fn(&SubArrayWithTraceIndex) -> String, { - if repeats.len() == 0 { + if repeats.is_empty() { return vec![]; } @@ -146,8 +143,9 @@ where let trace = log.get(repeat_set.trace_index).unwrap(); let mut set = HashSet::new(); let array = repeat_set.sub_array; - for index in array.start_index..(array.start_index + array.length) { - set.insert(trace[index]); + + for event in trace.iter().skip(array.start_index).take(array.length) { + set.insert(*event); } set @@ -165,21 +163,17 @@ where ))) }; - let mut activity_nodes = repeats - .iter() - .map(|repeat| create_activity_node(&repeat)) - .collect::>>>(); + let mut activity_nodes = repeats.iter().map(create_activity_node).collect::>>>(); - activity_nodes.sort_by(|first, second| second.borrow().len().cmp(&first.borrow().len())); + activity_nodes.sort_by_key(|item| std::cmp::Reverse(item.borrow().len())); let max_length = activity_nodes[0].borrow().len(); let mut top_level_nodes = vec![Rc::clone(&activity_nodes[0])]; let mut next_length_index = 1; let mut current_length = max_length; - for i in 1..activity_nodes.len() { - let node_ptr = &activity_nodes[i]; + for (index, node_ptr) in activity_nodes.iter().enumerate().skip(1) { if node_ptr.borrow().len() != max_length { - next_length_index = i; + next_length_index = index; current_length = node_ptr.borrow().len(); break; } diff --git a/Ficus/src/rust/ficus/src/features/analysis/patterns/repeats.rs b/Ficus/src/rust/ficus/src/features/analysis/patterns/repeats.rs index 17314d883..e8b8c0b25 100644 --- a/Ficus/src/rust/ficus/src/features/analysis/patterns/repeats.rs +++ b/Ficus/src/rust/ficus/src/features/analysis/patterns/repeats.rs @@ -24,7 +24,7 @@ where let mut push_repeats = |patterns: &[(usize, usize)]| { repeats.push( patterns - .into_iter() + .iter() .map(|repeat| SubArrayInTraceInfo::new(repeat.0, repeat.1 - repeat.0)) .collect(), ); @@ -45,7 +45,7 @@ where fn find_from_all_traces(log: &Vec>, finder: &TFinder, pusher: &mut TRepeatsPusher) where TFinder: Fn(&SuffixTree) -> Vec<(usize, usize)>, - TRepeatsPusher: FnMut(&[(usize, usize)]) -> (), + TRepeatsPusher: FnMut(&[(usize, usize)]), { for trace in log { let slice = SingleWordSuffixTreeSlice::new(trace.as_slice()); @@ -58,7 +58,7 @@ where fn find_from_single_merged_trace(log: &Vec>, finder: &TFinder, pusher: &mut TRepeatsPusher) where TFinder: Fn(&SuffixTree) -> Vec<(usize, usize)>, - TRepeatsPusher: FnMut(&[(usize, usize)]) -> (), + TRepeatsPusher: FnMut(&[(usize, usize)]), { let mut single_trace = vec![]; for trace in log { diff --git a/Ficus/src/rust/ficus/src/features/analysis/patterns/strict_loops.rs b/Ficus/src/rust/ficus/src/features/analysis/patterns/strict_loops.rs index 017b0545f..649f31d38 100644 --- a/Ficus/src/rust/ficus/src/features/analysis/patterns/strict_loops.rs +++ b/Ficus/src/rust/ficus/src/features/analysis/patterns/strict_loops.rs @@ -7,14 +7,14 @@ use crate::{ activity_instances::ActivityInTraceInfo, pattern_info::UnderlyingPatternKind, repeat_sets::{ActivityNode, SubArrayWithTraceIndex}, - tandem_arrays::{try_extract_tandem_array, TandemArrayInfo}, + tandem_arrays::{TandemArrayInfo, try_extract_tandem_array}, }, utils::display_name::get_display_name, }; use std::{cell::RefCell, collections::HashSet, rc::Rc}; pub fn find_loops_strict(log: &XesEventLogImpl, hashed_log: &Vec>, max_array_length: usize) -> Vec> { - find_tandem_arrays_strict(&hashed_log, max_array_length) + find_tandem_arrays_strict(hashed_log, max_array_length) .into_iter() .enumerate() .map(|(trace_index, trace_arrays)| { @@ -66,7 +66,7 @@ fn create_strict_loop_activity_instance( array: &TandemArrayInfo, trace_index: usize, trace: &XesTraceImpl, - hashed_trace: &Vec, + hashed_trace: &[u64], ) -> ActivityInTraceInfo { let repeat_count = *array.get_repeat_count(); let array = array.get_sub_array_info(); @@ -82,8 +82,8 @@ fn create_strict_loop_activity_instance( ActivityInTraceInfo::new( Rc::new(RefCell::new(ActivityNode::new( - Some(SubArrayWithTraceIndex::new(array.clone(), trace_index)), - HashSet::from_iter(hashed_trace[array.start_index..array.start_index + array.length].iter().map(|x| *x)), + Some(SubArrayWithTraceIndex::new(*array, trace_index)), + HashSet::from_iter(hashed_trace[array.start_index..array.start_index + array.length].iter().copied()), vec![], 0, Rc::new(Box::new(format!("Loop[{}]", name.join("::")))), diff --git a/Ficus/src/rust/ficus/src/features/analysis/patterns/tandem_arrays.rs b/Ficus/src/rust/ficus/src/features/analysis/patterns/tandem_arrays.rs index eae3ee0e6..0a7ab2704 100644 --- a/Ficus/src/rust/ficus/src/features/analysis/patterns/tandem_arrays.rs +++ b/Ficus/src/rust/ficus/src/features/analysis/patterns/tandem_arrays.rs @@ -53,7 +53,7 @@ pub fn find_primitive_tandem_arrays( find_primitive_tandem_arrays_with_length(log, max_tandem_array_length, include_length_one) .borrow() .iter() - .map(|trace_arrays| trace_arrays.into_iter().map(|array| array.sub_array).collect()) + .map(|trace_arrays| trace_arrays.iter().map(|array| array.sub_array).collect()) .collect() } @@ -70,7 +70,7 @@ pub fn find_primitive_tandem_arrays_with_length( let mut traces_primitive_arrays = Vec::new(); for array in trace_arrays { let mut is_primitive = true; - for length in 2..((array.sub_array.length + 1) / 2 + 1) { + for length in 2..(array.sub_array.length.div_ceil(2) + 1) { if try_extract_tandem_array(trace, array.sub_array.start_index, length).is_some() { is_primitive = false; break; @@ -95,7 +95,7 @@ pub fn find_maximal_tandem_arrays( ) -> Vec> { find_maximal_tandem_arrays_with_length(log, max_tandem_array_length, include_length_one) .iter() - .map(|trace_arrays| trace_arrays.into_iter().map(|array| array.sub_array).collect()) + .map(|trace_arrays| trace_arrays.iter().map(|array| array.sub_array).collect()) .collect() } @@ -133,12 +133,12 @@ pub fn find_maximal_tandem_arrays_with_length( result } -pub(super) fn try_extract_tandem_array(trace: &Vec, start_index: usize, length: usize) -> Option { +pub(super) fn try_extract_tandem_array(trace: &[u64], start_index: usize, length: usize) -> Option { let mut current_index = start_index + length; let mut repeat_count = 1; 'this_loop: loop { - if current_index + length - 1 >= trace.len() { + if current_index + length > trace.len() { break; } diff --git a/Ficus/src/rust/ficus/src/features/cases/mod.rs b/Ficus/src/rust/ficus/src/features/cases/mod.rs index df33bda9c..d66a1cb95 100644 --- a/Ficus/src/rust/ficus/src/features/cases/mod.rs +++ b/Ficus/src/rust/ficus/src/features/cases/mod.rs @@ -1,2 +1,17 @@ +#[derive(Clone, Debug)] +pub struct CaseName { + pub display_name: String, + pub name_parts: Vec, +} + +impl CaseName { + pub fn empty() -> Self { + Self { + name_parts: vec![], + display_name: "UNDEFINED".to_string(), + } + } +} + pub mod cases_discovery; mod cases_discovery_state; diff --git a/Ficus/src/rust/ficus/src/features/clustering/activities/activities_common.rs b/Ficus/src/rust/ficus/src/features/clustering/activities/activities_common.rs index d61fae643..b2634f66f 100644 --- a/Ficus/src/rust/ficus/src/features/clustering/activities/activities_common.rs +++ b/Ficus/src/rust/ficus/src/features/clustering/activities/activities_common.rs @@ -20,11 +20,11 @@ use crate::{ }, features::{ analysis::patterns::{ - activity_instances::{create_vector_of_underlying_events, ActivityInTraceInfo}, + activity_instances::{ActivityInTraceInfo, create_vector_of_underlying_events}, repeat_sets::ActivityNode, }, clustering::{ - common::{scale_raw_dataset_min_max, MyDataset}, + common::{MyDataset, scale_raw_dataset_min_max}, error::ClusteringError, }, }, @@ -106,7 +106,7 @@ fn create_activities_repr_from_subtraces( traces_activities: &TracesActivities, all_event_classes: &mut HashSet, params: &ActivitiesVisualizationParams, - event_classes_updater: impl Fn(&[Rc>], &mut HashMap, &mut HashSet) -> (), + event_classes_updater: impl Fn(&[Rc>], &mut HashMap, &mut HashSet), ) -> HashMap>, HashMap)> { let mut processed = HashMap::new(); for trace_activities in traces_activities.iter() { @@ -143,7 +143,7 @@ fn create_activities_repr_from_subtraces( .map(|x| { ( x.0.as_ref().as_ref().to_owned(), - (x.1 .0, x.1 .1.into_iter().map(|x| (x.0, x.1)).collect()), + (x.1.0, x.1.1.into_iter().map(|x| (x.0, x.1)).collect()), ) }) .collect() @@ -159,10 +159,9 @@ fn create_dataset_internal( ) -> Result>, HashMap)>, ClusteringError>, ) -> Result<(MyDataset, ActivityNodeWithCoords, Vec), ClusteringError> { let mut all_event_classes = HashSet::new(); - let regex_hasher = match class_extractor.as_ref() { - Some(class_extractor) => Some(RegexEventHasher::new(class_extractor).ok().unwrap()), - None => None, - }; + let regex_hasher = class_extractor + .as_ref() + .map(|class_extractor| RegexEventHasher::new(class_extractor).ok().unwrap()); let processed = activities_repr_fullfiller(traces_activities, regex_hasher.as_ref(), &mut all_event_classes)?; @@ -170,16 +169,12 @@ fn create_dataset_internal( all_event_classes.sort(); let mut processed = processed.iter().map(|x| x.1.clone()).collect::(); - processed.sort_by(|first, second| first.0.borrow().name().cmp(&second.0.borrow().name())); + processed.sort_by(|first, second| first.0.borrow().name().cmp(second.0.borrow().name())); let mut vector = vec![]; for activity in &processed { - for i in 0..all_event_classes.len() { - let count = if let Some(count) = activity.1.get(&all_event_classes[i]) { - *count - } else { - 0 - }; + for event_class in &all_event_classes { + let count = if let Some(count) = activity.1.get(event_class) { *count } else { 0 }; vector.push(count as f64); } diff --git a/Ficus/src/rust/ficus/src/features/clustering/activities/k_means.rs b/Ficus/src/rust/ficus/src/features/clustering/activities/k_means.rs index 475b78aca..7a3ea8739 100644 --- a/Ficus/src/rust/ficus/src/features/clustering/activities/k_means.rs +++ b/Ficus/src/rust/ficus/src/features/clustering/activities/k_means.rs @@ -10,7 +10,7 @@ use crate::{ features::{ analysis::patterns::repeat_sets::ActivityNode, clustering::{ - common::{create_colors_vector, transform_to_ficus_dataset, ClusteredDataset, MyDataset}, + common::{ClusteredDataset, MyDataset, create_colors_vector, transform_to_ficus_dataset}, error::{ClusteringError, ClusteringResult}, }, }, @@ -52,7 +52,7 @@ pub fn clusterize_activities_k_means( fn create_labeled_dataset_from_k_means( dataset: &MyDataset, clustered_dataset: &ClusteredDataset, - processed: &Vec<(Rc>, HashMap)>, + processed: &[(Rc>, HashMap)], classes_names: Vec, colors_holder: &mut ColorsHolder, ) -> LabeledDataset { @@ -78,7 +78,7 @@ fn create_k_means_model( KMeans::params_with(clusters_count, rand::thread_rng(), DistanceWrapper::new(distance)) .max_n_iterations(iterations_count) .tolerance(tolerance) - .fit(&dataset) + .fit(dataset) .expect("KMeans fitted") } diff --git a/Ficus/src/rust/ficus/src/features/clustering/activities/merging.rs b/Ficus/src/rust/ficus/src/features/clustering/activities/merging.rs index 77f36de5c..d89549e0b 100644 --- a/Ficus/src/rust/ficus/src/features/clustering/activities/merging.rs +++ b/Ficus/src/rust/ficus/src/features/clustering/activities/merging.rs @@ -63,7 +63,7 @@ pub(super) fn merge_activities( } let mut new_activity_name_parts = new_activity_name_parts.iter().map(|x| x.to_owned()).collect::>(); - new_activity_name_parts.sort_by(|first, second| first.cmp(second)); + new_activity_name_parts.sort(); let mut new_activity_name = String::new(); new_activity_name.push_str(create_cluster_name(*cluster).as_str()); @@ -74,7 +74,7 @@ pub(super) fn merge_activities( vec![], *cluster_activities[0].borrow().level(), Rc::new(Box::new(new_activity_name)), - cluster_activities.first().unwrap().borrow().pattern_kind().clone(), + *cluster_activities.first().unwrap().borrow().pattern_kind(), ); new_cluster_activities.insert(*cluster, Rc::new(RefCell::new(new_node))); diff --git a/Ficus/src/rust/ficus/src/features/clustering/common.rs b/Ficus/src/rust/ficus/src/features/clustering/common.rs index 3cc870390..457a9f731 100644 --- a/Ficus/src/rust/ficus/src/features/clustering/common.rs +++ b/Ficus/src/rust/ficus/src/features/clustering/common.rs @@ -35,14 +35,14 @@ pub fn transform_to_ficus_dataset(dataset: &MyDataset, processed: Vec, c FicusDataset::new(matrix, classes_names, processed) } -pub(super) fn create_colors_vector(labels: &Vec, colors_holder: &mut ColorsHolder) -> Vec { +pub(super) fn create_colors_vector(labels: &[usize], colors_holder: &mut ColorsHolder) -> Vec { labels .iter() .map(|x| colors_holder.get_or_create(&create_cluster_name(*x))) .collect() } -pub fn scale_raw_dataset_min_max(vector: &mut Vec, objects_count: usize, features_count: usize) { +pub fn scale_raw_dataset_min_max(vector: &mut [f64], objects_count: usize, features_count: usize) { for i in 0..features_count { let mut max = f64::MIN; let mut min = f64::MAX; @@ -68,7 +68,7 @@ pub(super) fn adjust_dbscan_labels(clusters: Array1>, put_noise_ev let mut next_label = clusters .iter() .filter(|c| c.is_some()) - .map(|c| c.as_ref().unwrap().clone()) + .map(|c| *c.as_ref().unwrap()) .max() .unwrap_or(0); diff --git a/Ficus/src/rust/ficus/src/features/clustering/error.rs b/Ficus/src/rust/ficus/src/features/clustering/error.rs index 520c2389b..61a45cef7 100644 --- a/Ficus/src/rust/ficus/src/features/clustering/error.rs +++ b/Ficus/src/rust/ficus/src/features/clustering/error.rs @@ -2,6 +2,7 @@ use crate::{ pipelines::errors::pipeline_errors::{PipelinePartExecutionError, RawPartExecutionError}, utils::dataset::dataset::LabeledDataset, }; +use std::fmt::Display; pub type ClusteringResult = Result; @@ -12,19 +13,22 @@ pub enum ClusteringError { RawError(String), } -impl Into for ClusteringError { - fn into(self) -> PipelinePartExecutionError { - PipelinePartExecutionError::Raw(RawPartExecutionError::new(self.to_string())) +impl From for PipelinePartExecutionError { + fn from(val: ClusteringError) -> Self { + PipelinePartExecutionError::Raw(RawPartExecutionError::new(val.to_string())) } } -impl ToString for ClusteringError { - fn to_string(&self) -> String { - match self { - Self::NoRepeatSet => "NoRepeatSet".to_owned(), - Self::FailedToCreateNdArray => "FailedToCreateNdArray".to_owned(), - Self::FailedToCalculateSilhouetteScore => "FailedToCalculateSilhouetteScore".to_owned(), - Self::RawError(message) => message.clone(), - } +impl Display for ClusteringError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str( + match self { + Self::NoRepeatSet => "NoRepeatSet".to_owned(), + Self::FailedToCreateNdArray => "FailedToCreateNdArray".to_owned(), + Self::FailedToCalculateSilhouetteScore => "FailedToCalculateSilhouetteScore".to_owned(), + Self::RawError(message) => message.clone(), + } + .as_str(), + ) } } diff --git a/Ficus/src/rust/ficus/src/features/clustering/traces/common.rs b/Ficus/src/rust/ficus/src/features/clustering/traces/common.rs index 6f91b12b2..86f1c7577 100644 --- a/Ficus/src/rust/ficus/src/features/clustering/traces/common.rs +++ b/Ficus/src/rust/ficus/src/features/clustering/traces/common.rs @@ -10,7 +10,7 @@ use crate::{ features::{ analysis::patterns::activity_instances::{create_vector_of_immediate_underlying_events, create_vector_of_underlying_events}, clustering::{ - common::{create_colors_vector, scale_raw_dataset_min_max, transform_to_ficus_dataset, MyDataset}, + common::{MyDataset, create_colors_vector, scale_raw_dataset_min_max, transform_to_ficus_dataset}, error::ClusteringError, traces::traces_params::{FeatureCountKind, TracesClusteringParams, TracesRepresentationSource}, }, @@ -24,9 +24,9 @@ use crate::{ use getset::Getters; use linfa::DatasetBase; use linfa_nn::{ - distance::Distance, CommonNearestNeighbour, CommonNearestNeighbour::{KdTree, LinearSearch}, + distance::Distance, }; use log::warn; use ndarray::Array2; @@ -74,7 +74,7 @@ pub fn do_clusterize_log_by_traces( } let new_logs = new_logs.into_iter().map(|x| x.1).collect(); - let colors = create_colors_vector(&labels, &mut params.vis_params.colors_holder); + let colors = create_colors_vector(&labels, params.vis_params.colors_holder); Ok((new_logs, LabeledDataset::new(ficus_dataset, labels, colors))) } @@ -139,10 +139,9 @@ fn create_traces_dataset_default_internal( feature_count_kind: FeatureCountKind, trace_repr_creator: impl Fn(&TLog::TTrace) -> Vec>>, ) -> Result<(MyDataset, Vec, Vec), ClusteringError> { - let regex_hasher = match class_extractor.as_ref() { - Some(class_extractor) => Some(RegexEventHasher::new(class_extractor).ok().unwrap()), - None => None, - }; + let regex_hasher = class_extractor + .as_ref() + .map(|class_extractor| RegexEventHasher::new(class_extractor).ok().unwrap()); let mut processed_traces = vec![]; for trace in log.traces() { @@ -210,7 +209,7 @@ fn create_traces_dataset_default_internal( Ok(( DatasetBase::from(array), - (0..processed_traces.len()).into_iter().map(|x| format!("Trace_{}", x)).collect(), + (0..processed_traces.len()).map(|x| format!("Trace_{}", x)).collect(), all_event_classes, )) } @@ -228,10 +227,9 @@ fn create_traces_dataset_levenshtein_internal( class_extractor: Option<&String>, trace_repr_creator: impl Fn(&TLog::TTrace) -> Vec>>, ) -> Result<(MyDataset, Vec, Vec), ClusteringError> { - let regex_hasher = match class_extractor.as_ref() { - Some(class_extractor) => Some(RegexEventHasher::new(class_extractor).ok().unwrap()), - None => None, - }; + let regex_hasher = class_extractor + .as_ref() + .map(|class_extractor| RegexEventHasher::new(class_extractor).ok().unwrap()); let mut processed_traces = vec![]; for trace in log.traces() { @@ -282,8 +280,8 @@ fn create_traces_dataset_levenshtein_internal( Ok(( DatasetBase::from(array), - (0..processed_traces.len()).into_iter().map(|x| format!("Trace_{}", x)).collect(), - (0..max_length).into_iter().map(|x| format!("Symbol_{}", x)).collect(), + (0..processed_traces.len()).map(|x| format!("Trace_{}", x)).collect(), + (0..max_length).map(|x| format!("Symbol_{}", x)).collect(), )) } @@ -312,13 +310,10 @@ impl BestSilhouetteLabels { } pub fn process(&mut self, labels: Vec, distance_func: &dyn Fn(usize, usize) -> f64) { - let score = match silhouette_score(&labels, |first, second| distance_func(first, second)) { + let score = match silhouette_score(&labels, distance_func) { Ok(score) => score, Err(err) => { - warn!( - "Failed to calculate silhouette score, skipping those labels, reason: {}", - err.to_string() - ); + warn!("Failed to calculate silhouette score, skipping those labels, reason: {}", err); if self.labels.is_none() { self.labels = Some(labels); } diff --git a/Ficus/src/rust/ficus/src/features/clustering/traces/dbscan.rs b/Ficus/src/rust/ficus/src/features/clustering/traces/dbscan.rs index a0abf2813..113d42126 100644 --- a/Ficus/src/rust/ficus/src/features/clustering/traces/dbscan.rs +++ b/Ficus/src/rust/ficus/src/features/clustering/traces/dbscan.rs @@ -4,7 +4,7 @@ use crate::{ features::clustering::{ common::adjust_dbscan_labels, error::ClusteringError, - traces::common::{calculate_distance, do_clusterize_log_by_traces, BestSilhouetteLabels}, + traces::common::{BestSilhouetteLabels, calculate_distance, do_clusterize_log_by_traces}, }, utils::{dataset::dataset::LabeledDataset, distance::distance::DistanceWrapper}, }; diff --git a/Ficus/src/rust/ficus/src/features/clustering/traces/k_means.rs b/Ficus/src/rust/ficus/src/features/clustering/traces/k_means.rs index 645c19bab..73919acc5 100644 --- a/Ficus/src/rust/ficus/src/features/clustering/traces/k_means.rs +++ b/Ficus/src/rust/ficus/src/features/clustering/traces/k_means.rs @@ -3,7 +3,7 @@ use crate::{ features::clustering::{ error::ClusteringError, traces::{ - common::{calculate_distance, do_clusterize_log_by_traces, BestSilhouetteLabels}, + common::{BestSilhouetteLabels, calculate_distance, do_clusterize_log_by_traces}, traces_params::TracesClusteringParams, }, }, @@ -24,7 +24,7 @@ pub fn clusterize_log_by_traces_kmeans_grid_search( let model = KMeans::params_with(clusters_count, rand::thread_rng(), DistanceWrapper::new(params.distance)) .max_n_iterations(max_iterations_count) .tolerance(tolerance) - .fit(&dataset) + .fit(dataset) .expect("KMeans fitted"); let clustered_dataset = model.predict(dataset.clone()); diff --git a/Ficus/src/rust/ficus/src/features/discovery/alpha/alpha.rs b/Ficus/src/rust/ficus/src/features/discovery/alpha/alpha.rs index b3058a75d..4c48870cf 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/alpha/alpha.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/alpha/alpha.rs @@ -93,10 +93,10 @@ fn add_alpha_plus_plus_transitions(provider: &impl AlphaPlusRelationsProvider, p for outgoing_arc in transition.outgoing_arcs() { if outgoing_arc.place_id() != place.id() { let outgoing_place = petri_net.place(&outgoing_arc.place_id()); - if let Some(outgoing_alpha_set) = outgoing_place.user_data().concrete(key) { - if alpha_set.is_full_subset(outgoing_alpha_set) { - transitions_connections.insert((transition.id(), outgoing_place.id())); - } + if let Some(outgoing_alpha_set) = outgoing_place.user_data().concrete(key) + && alpha_set.is_full_subset(outgoing_alpha_set) + { + transitions_connections.insert((transition.id(), outgoing_place.id())); } } } @@ -104,10 +104,10 @@ fn add_alpha_plus_plus_transitions(provider: &impl AlphaPlusRelationsProvider, p for incoming_arc in transition.incoming_arcs() { if incoming_arc.place_id() != place.id() { let incoming_place = petri_net.place(&incoming_arc.place_id()); - if let Some(incoming_alpha_set) = incoming_place.user_data().concrete(key) { - if alpha_set.is_full_subset(incoming_alpha_set) { - places_connections.insert((incoming_place.id(), transition.id())); - } + if let Some(incoming_alpha_set) = incoming_place.user_data().concrete(key) + && alpha_set.is_full_subset(incoming_alpha_set) + { + places_connections.insert((incoming_place.id(), transition.id())); } } } @@ -164,7 +164,7 @@ fn create_initial_sets(provider: &impl AlphaRelationsProvider) -> HashSet 0 && set.right_classes().len() > 0) + .filter(|set| !set.left_classes().is_empty() && !set.right_classes().is_empty()) .collect() } @@ -173,7 +173,7 @@ fn maximize_sets(current_sets: HashSet, provider: &impl AlphaRelations let should_extend = (first.is_left_subset(second) || first.is_right_subset(second)) && first.can_extend(second, provider); match should_extend { - true => Some(first.extend(&second)), + true => Some(first.extend(second)), false => None, } }) diff --git a/Ficus/src/rust/ficus/src/features/discovery/alpha/alpha_plus_plus_nfc/alpha_plus_plus_nfc.rs b/Ficus/src/rust/ficus/src/features/discovery/alpha/alpha_plus_plus_nfc/alpha_plus_plus_nfc.rs index 0fc07f638..4e2e1978b 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/alpha/alpha_plus_plus_nfc/alpha_plus_plus_nfc.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/alpha/alpha_plus_plus_nfc/alpha_plus_plus_nfc.rs @@ -7,13 +7,13 @@ use crate::{ }, discovery::{ alpha::{ - alpha::{discover_petri_net_alpha, discover_petri_net_alpha_plus, find_transitions_one_length_loop, ALPHA_SET}, + alpha::{ALPHA_SET, discover_petri_net_alpha, discover_petri_net_alpha_plus, find_transitions_one_length_loop}, alpha_plus_plus_nfc::{alpha_plus_plus_nfc_triple::AlphaPlusPlusNfcTriple, extended_alpha_set::ExtendedAlphaSet, w3_pair::W3Pair}, providers::alpha_plus_nfc_provider::AlphaPlusNfcRelationsProvider, utils::maximize, }, petri_net::{petri_net::DefaultPetriNet, place::Place, transition::Transition}, - relations::triangle_relation::{OfflineTriangleRelation, TriangleRelation}, + relations::triangle_relation::OfflineTriangleRelation, }, }, utils::{sets::two_sets::TwoSets, user_data::user_data::UserData}, @@ -165,7 +165,7 @@ pub fn discover_petri_net_alpha_plus_plus_nfc(log: &TLog) -> Def let mut p_w = HashSet::new(); let check_should_add_to_pw = |two_sets: &TwoSets<&String>| { for l_w_item in &l_w { - if l_w_item.a_classes().eq(&two_sets.first_set()) && l_w_item.b_classes().eq(&two_sets.second_set()) { + if l_w_item.a_classes().eq(two_sets.first_set()) && l_w_item.b_classes().eq(two_sets.second_set()) { return false; } } @@ -192,12 +192,7 @@ pub fn discover_petri_net_alpha_plus_plus_nfc(log: &TLog) -> Def let mut resulting_net = DefaultPetriNet::empty(); let mut transitions_to_ids = HashMap::new(); - for transition in info - .all_event_classes() - .iter() - .map(|c| *c) - .chain(one_length_loop_transitions.iter()) - { + for transition in info.all_event_classes().iter().copied().chain(one_length_loop_transitions.iter()) { let id = resulting_net.add_transition(Transition::empty((*transition).to_owned(), false, Some((*transition).to_owned()))); transitions_to_ids.insert(transition, id); } @@ -230,7 +225,7 @@ fn eliminate_by_reduction_rule_1( if (provider.w2_relation(a, b, petri_net) && provider.concave_arrow_relation(b, c)) || (provider.w2_relation(b, c, petri_net) && provider.concave_arrow_relation(a, b)) { - to_remove.push(w2_relation.clone()); + to_remove.push(*w2_relation); } } } @@ -258,10 +253,10 @@ fn construct_w3_transitive_closure_cache<'a>(w3_relations: &'a HashSet<(&'a Stri for first_class in &all_classes { for second_class in &all_classes { - if let Some(children) = graph.get(first_class) { - if children.contains(second_class) { - continue; - } + if let Some(children) = graph.get(first_class) + && children.contains(second_class) + { + continue; } let mut is_in_closure = false; @@ -298,10 +293,10 @@ fn construct_w3_transitive_closure_cache<'a>(w3_relations: &'a HashSet<(&'a Stri fn eliminate_w3_relations_by_rule_2(w3_relations: &mut HashSet<(&String, &String)>, closure_cache: &HashMap>) { let mut to_remove = HashSet::new(); for relation in w3_relations.iter() { - if let Some(children) = closure_cache.get(relation.0) { - if children.contains(relation.1) { - to_remove.insert(relation.clone()); - } + if let Some(children) = closure_cache.get(relation.0) + && children.contains(relation.1) + { + to_remove.insert(*relation); } } diff --git a/Ficus/src/rust/ficus/src/features/discovery/alpha/alpha_plus_plus_nfc/alpha_plus_plus_nfc_triple.rs b/Ficus/src/rust/ficus/src/features/discovery/alpha/alpha_plus_plus_nfc/alpha_plus_plus_nfc_triple.rs index 01570e745..d6a4790cf 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/alpha/alpha_plus_plus_nfc/alpha_plus_plus_nfc_triple.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/alpha/alpha_plus_plus_nfc/alpha_plus_plus_nfc_triple.rs @@ -8,6 +8,7 @@ use crate::{ }; use std::{ collections::BTreeSet, + fmt::Display, hash::{Hash, Hasher}, }; @@ -41,7 +42,7 @@ impl<'a> AlphaPlusPlusNfcTriple<'a> { pub fn try_merge(first: &Self, second: &Self, provider: &AlphaPlusNfcRelationsProvider<'a, TLog>) -> Option { let merge_sets = |first: &BTreeSet<&'a String>, second: &BTreeSet<&'a String>| -> BTreeSet<&'a String> { - first.iter().chain(second.iter()).map(|class| *class).collect() + first.iter().chain(second.iter()).copied().collect() }; let new_triple = Self { @@ -86,7 +87,7 @@ impl<'a> AlphaPlusPlusNfcTriple<'a> { let first = self.a_classes.iter().chain(self.c_classes.iter()); let second = self.b_classes.iter().chain(self.c_classes.iter()); - TwoSets::new(first.map(|c| *c).collect(), second.map(|c| *c).collect()) + TwoSets::new(first.copied().collect(), second.copied().collect()) } pub fn a_classes(&self) -> &BTreeSet<&'a String> { @@ -130,8 +131,8 @@ impl<'a> Clone for AlphaPlusPlusNfcTriple<'a> { impl<'a> Eq for AlphaPlusPlusNfcTriple<'a> {} -impl<'a> ToString for AlphaPlusPlusNfcTriple<'a> { - fn to_string(&self) -> String { +impl<'a> Display for AlphaPlusPlusNfcTriple<'a> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let mut repr = String::new(); repr.push('('); @@ -143,7 +144,7 @@ impl<'a> ToString for AlphaPlusPlusNfcTriple<'a> { repr.push(',') } - if set.len() > 0 { + if !set.is_empty() { repr.remove(repr.len() - 1); } @@ -158,6 +159,7 @@ impl<'a> ToString for AlphaPlusPlusNfcTriple<'a> { repr.remove(repr.len() - 1); repr.push(')'); - repr + + write!(f, "{}", repr) } } diff --git a/Ficus/src/rust/ficus/src/features/discovery/alpha/alpha_plus_plus_nfc/extended_alpha_set.rs b/Ficus/src/rust/ficus/src/features/discovery/alpha/alpha_plus_plus_nfc/extended_alpha_set.rs index f193f6468..cc12038f7 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/alpha/alpha_plus_plus_nfc/extended_alpha_set.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/alpha/alpha_plus_plus_nfc/extended_alpha_set.rs @@ -8,6 +8,7 @@ use crate::{ }; use std::{ collections::{BTreeSet, HashSet}, + fmt::Display, hash::{Hash, Hasher}, }; @@ -156,8 +157,8 @@ impl<'a> ExtendedAlphaSet<'a> { pub fn merge(&self, other: &Self) -> Self { Self { alpha_set: self.alpha_set.extend(&other.alpha_set), - left_extension: self.left_extension.iter().chain(&other.left_extension).map(|c| *c).collect(), - right_extension: self.right_extension.iter().chain(&other.right_extension).map(|c| *c).collect(), + left_extension: self.left_extension.iter().chain(&other.left_extension).copied().collect(), + right_extension: self.right_extension.iter().chain(&other.right_extension).copied().collect(), } } @@ -168,7 +169,7 @@ impl<'a> ExtendedAlphaSet<'a> { let second = self.alpha_set.right_classes(); let second = second.iter().chain(self.right_extension.iter()); - TwoSets::new(first.map(|c| *c).collect(), second.map(|c| *c).collect()) + TwoSets::new(first.copied().collect(), second.copied().collect()) } pub fn alpha_set(&self) -> &AlphaSet { @@ -197,8 +198,8 @@ impl<'a> PartialEq for ExtendedAlphaSet<'a> { impl<'a> Eq for ExtendedAlphaSet<'a> {} -impl<'a> ToString for ExtendedAlphaSet<'a> { - fn to_string(&self) -> String { +impl<'a> Display for ExtendedAlphaSet<'a> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let mut repr = String::new(); repr.push('('); repr.push_str(self.alpha_set.to_string().as_str()); @@ -211,7 +212,7 @@ impl<'a> ToString for ExtendedAlphaSet<'a> { repr.push(','); } - if set.len() > 0 { + if !set.is_empty() { repr.remove(repr.len() - 1); } @@ -225,7 +226,8 @@ impl<'a> ToString for ExtendedAlphaSet<'a> { repr.remove(repr.len() - 1); repr.push(')'); - repr + + write!(f, "{}", repr) } } @@ -233,8 +235,8 @@ impl<'a> Clone for ExtendedAlphaSet<'a> { fn clone(&self) -> Self { Self { alpha_set: self.alpha_set.clone(), - left_extension: self.left_extension.iter().map(|c| *c).collect(), - right_extension: self.right_extension.iter().map(|c| *c).collect(), + left_extension: self.left_extension.iter().copied().collect(), + right_extension: self.right_extension.iter().copied().collect(), } } } diff --git a/Ficus/src/rust/ficus/src/features/discovery/alpha/alpha_plus_plus_nfc/w3_pair.rs b/Ficus/src/rust/ficus/src/features/discovery/alpha/alpha_plus_plus_nfc/w3_pair.rs index 4990bf992..dd455b690 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/alpha/alpha_plus_plus_nfc/w3_pair.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/alpha/alpha_plus_plus_nfc/w3_pair.rs @@ -5,6 +5,7 @@ use crate::{ }; use std::{ collections::HashSet, + fmt::Display, hash::{Hash, Hasher}, }; @@ -93,8 +94,8 @@ impl<'a> Clone for W3Pair<'a> { } } -impl<'a> ToString for W3Pair<'a> { - fn to_string(&self) -> String { - self.two_sets.to_string() +impl<'a> Display for W3Pair<'a> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(self.two_sets.to_string().as_str()) } } diff --git a/Ficus/src/rust/ficus/src/features/discovery/alpha/alpha_set.rs b/Ficus/src/rust/ficus/src/features/discovery/alpha/alpha_set.rs index d766c3a8f..042c0a6d0 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/alpha/alpha_set.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/alpha/alpha_set.rs @@ -2,7 +2,10 @@ use crate::{ features::discovery::alpha::providers::alpha_provider::AlphaRelationsProvider, utils::{hash_utils::compare_based_on_hashes, sets::two_sets::TwoSets}, }; -use std::hash::{Hash, Hasher}; +use std::{ + fmt::Display, + hash::{Hash, Hasher}, +}; #[derive(Debug)] pub struct AlphaSet { @@ -83,7 +86,7 @@ impl AlphaSet { } } - return true; + true } pub fn extend(&self, other: &Self) -> AlphaSet { @@ -107,9 +110,9 @@ impl PartialEq for AlphaSet { impl Eq for AlphaSet {} -impl ToString for AlphaSet { - fn to_string(&self) -> String { - self.two_sets.to_string() +impl Display for AlphaSet { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(self.two_sets.to_string().as_str()) } } diff --git a/Ficus/src/rust/ficus/src/features/discovery/alpha/alpha_sharp.rs b/Ficus/src/rust/ficus/src/features/discovery/alpha/alpha_sharp.rs index adbe40306..eb94f5302 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/alpha/alpha_sharp.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/alpha/alpha_sharp.rs @@ -19,6 +19,7 @@ use crate::{ use log::debug; use std::{ collections::{BTreeSet, HashSet}, + fmt::Display, hash::{Hash, Hasher}, }; @@ -51,8 +52,8 @@ impl<'a> AlphaSharpTuple<'a> { pub fn try_merge(first: &Self, second: &Self) -> Option { let new = Self { provider: first.provider, - p_in: BTreeSet::from_iter(first.p_in.iter().chain(second.p_in.iter()).map(|c| c.clone())), - p_out: BTreeSet::from_iter(first.p_out.iter().chain(second.p_out.iter()).map(|c| c.clone())), + p_in: BTreeSet::from_iter(first.p_in.iter().chain(second.p_in.iter()).cloned()), + p_out: BTreeSet::from_iter(first.p_out.iter().chain(second.p_out.iter()).cloned()), }; match new.valid() { @@ -145,8 +146,8 @@ impl<'a> PartialEq for AlphaSharpTuple<'a> { impl<'a> Eq for AlphaSharpTuple<'a> {} -impl<'a> ToString for AlphaSharpTuple<'a> { - fn to_string(&self) -> String { +impl<'a> Display for AlphaSharpTuple<'a> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let mut string = String::new(); string.push('('); @@ -157,10 +158,10 @@ impl<'a> ToString for AlphaSharpTuple<'a> { string.push('{'); for class in &tuple.0 { string.push_str(class.as_str()); - string.push_str(",") + string.push(',') } - if tuple.0.len() > 0 { + if !tuple.0.is_empty() { string.remove(string.len() - 1); } @@ -168,18 +169,18 @@ impl<'a> ToString for AlphaSharpTuple<'a> { for class in &tuple.1 { string.push_str(class.as_str()); - string.push_str(",") + string.push(',') } - if tuple.1.len() > 0 { + if !tuple.1.is_empty() { string.remove(string.len() - 1); } - string.push_str("}"); + string.push('}'); string.push_str("),"); } - if set.len() > 0 { + if !set.is_empty() { string.remove(string.len() - 1); } @@ -193,7 +194,8 @@ impl<'a> ToString for AlphaSharpTuple<'a> { string.remove(string.len() - 1); string.push(')'); - string + + write!(f, "{}", string) } } @@ -202,12 +204,7 @@ impl<'a> Clone for AlphaSharpTuple<'a> { let construct_set = |set: &AlphaSharpSet<'a>| -> AlphaSharpSet<'a> { set .iter() - .map(|t| { - ( - BTreeSet::from_iter(t.0.iter().map(|r| *r)), - BTreeSet::from_iter(t.0.iter().map(|r| *r)), - ) - }) + .map(|t| (BTreeSet::from_iter(t.0.iter().copied()), BTreeSet::from_iter(t.0.iter().copied()))) .collect() }; @@ -254,12 +251,12 @@ pub fn discover_petri_net_alpha_sharp(log: &impl EventLog, triangle_relation: &d } for x in &sharp_tuples { - debug!("{}", x.to_string()); + debug!("{}", x); } - let current_set = maximize(sharp_tuples, |first, second| AlphaSharpTuple::try_merge(first, second)); + let current_set = maximize(sharp_tuples, AlphaSharpTuple::try_merge); for x in ¤t_set { - debug!("{}", x.to_string()); + debug!("{}", x); } } diff --git a/Ficus/src/rust/ficus/src/features/discovery/alpha/providers/alpha_plus_nfc_provider.rs b/Ficus/src/rust/ficus/src/features/discovery/alpha/providers/alpha_plus_nfc_provider.rs index 74597a16e..c87f05dfa 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/alpha/providers/alpha_plus_nfc_provider.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/alpha/providers/alpha_plus_nfc_provider.rs @@ -20,13 +20,13 @@ enum PrePostSet { PostSet, } -const RIGHT_DOUBLE_ARROW_CACHE: &'static str = "right_double_arrow_cache"; -const W1_CACHE: &'static str = "w1_cache"; -const W21_CACHE: &'static str = "w21_cache"; -const W22_CACHE: &'static str = "w22_cache"; -const W3_CACHE: &'static str = "w3_cache"; +const RIGHT_DOUBLE_ARROW_CACHE: &str = "right_double_arrow_cache"; +const W1_CACHE: &str = "w1_cache"; +const W21_CACHE: &str = "w21_cache"; +const W22_CACHE: &str = "w22_cache"; +const W3_CACHE: &str = "w3_cache"; -static RELATIONS_NAMES: &'static [&'static str] = &[RIGHT_DOUBLE_ARROW_CACHE, W1_CACHE, W21_CACHE, W22_CACHE, W3_CACHE]; +static RELATIONS_NAMES: &[&str] = &[RIGHT_DOUBLE_ARROW_CACHE, W1_CACHE, W21_CACHE, W22_CACHE, W3_CACHE]; pub struct AlphaPlusNfcRelationsProvider<'a, TLog> where @@ -165,31 +165,31 @@ where continue; } - if events[i].borrow().name() == second { - if let Some(first_index) = last_first_index { - let mut all_suitable = true; - let mut actual_length = 0; - - for j in (first_index + 1)..i { - let event = events[j].borrow(); - let event_name = event.name(); - if self.log_info().event_count(event_name) == 0 { - continue; - } - - actual_length += 1; - if self.left_triangle_relation(event_name, first) || self.right_triangle_relation(event_name, first) { - all_suitable = false; - break; - } + if events[i].borrow().name() == second + && let Some(first_index) = last_first_index + { + let mut all_suitable = true; + let mut actual_length = 0; + + for j in (first_index + 1)..i { + let event = events[j].borrow(); + let event_name = event.name(); + if self.log_info().event_count(event_name) == 0 { + continue; } - if all_suitable && actual_length > 0 { - return true; + actual_length += 1; + if self.left_triangle_relation(event_name, first) || self.right_triangle_relation(event_name, first) { + all_suitable = false; + break; } + } - last_first_index = None; + if all_suitable && actual_length > 0 { + return true; } + + last_first_index = None; } } } @@ -423,12 +423,12 @@ where let second_streak_pre_set = Self::get_pre_or_post_set(petri_net, second_streak, PrePostSet::PreSet); let first_intersection: HashSet<&u64> = first_post_set.intersection(&first_streak_post_set).collect(); - if first_intersection.len() == 0 { + if first_intersection.is_empty() { continue; } let second_intersection: HashSet<&u64> = second_pre_set.intersection(&second_streak_pre_set).collect(); - if second_intersection.len() == 0 { + if second_intersection.is_empty() { continue; } @@ -460,7 +460,7 @@ where let task_pre_set = Self::get_pre_or_post_set(petri_net, task, PrePostSet::PreSet); let intersection: HashSet<&u64> = second_pre_set.intersection(&task_pre_set).collect(); - if intersection.len() == 0 { + if intersection.is_empty() { continue; } @@ -489,7 +489,7 @@ where PrePostSet::PostSet => transition.outgoing_arcs(), }; - return arcs.iter().map(|arc| arc.place_id()).collect(); + arcs.iter().map(|arc| arc.place_id()).collect() } pub fn add_additional_causal_relation(&mut self, first: &'a String, second: &'a String) { diff --git a/Ficus/src/rust/ficus/src/features/discovery/alpha/providers/relations_cache.rs b/Ficus/src/rust/ficus/src/features/discovery/alpha/providers/relations_cache.rs index debf2eca6..b727c1c3e 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/alpha/providers/relations_cache.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/alpha/providers/relations_cache.rs @@ -10,10 +10,10 @@ impl RelationsCache { } pub fn try_get(&self, first: &str, second: &str) -> Option<&T> { - if let Some(map) = self.cache.get(first) { - if let Some(value) = map.get(second) { - return Some(value); - } + if let Some(map) = self.cache.get(first) + && let Some(value) = map.get(second) + { + return Some(value); } None diff --git a/Ficus/src/rust/ficus/src/features/discovery/alpha/utils.rs b/Ficus/src/rust/ficus/src/features/discovery/alpha/utils.rs index 1018f18d1..d86c6a721 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/alpha/utils.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/alpha/utils.rs @@ -14,13 +14,13 @@ pub fn maximize( for i in 0..vec.len() { for j in 0..vec.len() { - if i != j { - if let Some(merged) = merger(vec.get(i).unwrap(), vec.get(j).unwrap()) { - any_change = true; - new_elements.insert(merged); - merged_indices.insert(i); - merged_indices.insert(j); - } + if i != j + && let Some(merged) = merger(vec.get(i).unwrap(), vec.get(j).unwrap()) + { + any_change = true; + new_elements.insert(merged); + merged_indices.insert(i); + merged_indices.insert(j); } } } @@ -29,9 +29,9 @@ pub fn maximize( break; } - for i in 0..vec.len() { + for (i, element) in vec.iter().enumerate() { if !merged_indices.contains(&i) { - new_elements.insert(vec[i].clone()); + new_elements.insert((*element).clone()); } } diff --git a/Ficus/src/rust/ficus/src/features/discovery/root_sequence/adjustments.rs b/Ficus/src/rust/ficus/src/features/discovery/ecfg/adjustments.rs similarity index 89% rename from Ficus/src/rust/ficus/src/features/discovery/root_sequence/adjustments.rs rename to Ficus/src/rust/ficus/src/features/discovery/ecfg/adjustments.rs index e8659d2e3..6ca974f7d 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/root_sequence/adjustments.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/ecfg/adjustments.rs @@ -1,15 +1,15 @@ use crate::{ features::discovery::{ - petri_net::annotations::{PerformanceAnnotationInfo, PerformanceMap, PERFORMANCE_ANNOTATION_INFO_KEY}, - root_sequence::{ + ecfg::{ context::DiscoveryContext, context_keys::{ NODE_CORRESPONDING_TRACE_DATA_KEY, NODE_INNER_GRAPH_KEY, NODE_SOFTWARE_DATA_KEY, NODE_START_END_ACTIVITIES_TIMES_KEY, NODE_START_END_ACTIVITY_TIME_KEY, }, - discovery::{replay_sequence_with_history, EVENT_UNIQUE_ID_KEY}, - models::{ActivityStartEndTimeData, DiscoverRootSequenceGraphError, EventWithUniqueId, NodeAdditionalDataContainer}, + discovery::{EVENT_UNIQUE_ID_KEY, replay_sequence_with_history}, + models::{ActivityStartEndTimeData, DiscoverECFGError, EventWithUniqueId, NodeAdditionalDataContainer}, }, + petri_net::annotations::{PERFORMANCE_ANNOTATION_INFO_KEY, PerformanceAnnotationInfo, PerformanceMap}, }, utils::{ context_key::DefaultContextKey, @@ -104,7 +104,7 @@ struct NeededNodesIds { } impl NeededNodesIds { - pub fn new(graph: &DefaultGraph, sequence: &Vec) -> Self { + pub fn new(graph: &DefaultGraph, sequence: &[u64]) -> Self { let first_node = *sequence.first().unwrap(); let last_node = *sequence.last().unwrap(); @@ -131,11 +131,11 @@ fn connect_added_merged_node_to_graph(nodes_ids: &NeededNodesIds, added_node: &u graph.connect_nodes( &nodes_ids.start_node, - &added_node, + added_node, NodesConnectionData::new(None, start_node_edge_weight, None), ); graph.connect_nodes( - &added_node, + added_node, &nodes_ids.end_node, NodesConnectionData::new(None, end_node_edge_weight, None), ); @@ -172,31 +172,31 @@ fn create_merged_node(nodes: &Vec, graph: &mut DefaultGraph) -> u64 { fn put_activities_times(added_node_id: &u64, nodes: &Vec, graph: &mut DefaultGraph) { let activities_times = collect_start_end_time_activities_data(nodes, graph); graph - .node_mut(&added_node_id) + .node_mut(added_node_id) .unwrap() .user_data_mut() .put_concrete(NODE_START_END_ACTIVITIES_TIMES_KEY.key(), activities_times); } fn put_trace_data(added_node_id: &u64, nodes: &Vec, graph: &mut DefaultGraph) { - let trace_data = extract_user_data_from(nodes, &graph, &NODE_CORRESPONDING_TRACE_DATA_KEY); + let trace_data = extract_user_data_from(nodes, graph, &NODE_CORRESPONDING_TRACE_DATA_KEY); graph - .node_mut(&added_node_id) + .node_mut(added_node_id) .unwrap() .user_data_mut() .put_concrete(NODE_CORRESPONDING_TRACE_DATA_KEY.key(), trace_data); } fn put_software_data(added_node_id: &u64, nodes: &Vec, graph: &mut DefaultGraph) { - let software_data = extract_user_data_from(nodes, &graph, &NODE_SOFTWARE_DATA_KEY); + let software_data = extract_user_data_from(nodes, graph, &NODE_SOFTWARE_DATA_KEY); graph - .node_mut(&added_node_id) + .node_mut(added_node_id) .unwrap() .user_data_mut() .put_concrete(NODE_SOFTWARE_DATA_KEY.key(), software_data); } -fn disconnect_and_delete_nodes(nodes: &Vec, graph: &mut DefaultGraph) { +fn disconnect_and_delete_nodes(nodes: &[u64], graph: &mut DefaultGraph) { for i in 0..nodes.len() - 1 { graph.disconnect_nodes(&nodes[i], &nodes[i + 1]); graph.delete_node(&nodes[i]); @@ -214,14 +214,14 @@ fn put_performance_additional_infos( put_performance_annotation_info( &nodes_ids.start_node, &nodes_ids.first_node, - (&nodes_ids.start_node, &added_node_id), + (&nodes_ids.start_node, added_node_id), performance_map, graph, ); put_performance_annotation_info( &nodes_ids.last_node, &nodes_ids.end_node, - (&added_node_id, &nodes_ids.end_node), + (added_node_id, &nodes_ids.end_node), performance_map, graph, ); @@ -288,8 +288,8 @@ pub fn adjust_connections( for trace in log { for i in 0..trace.len() - 1 { - let first_name = name_extractor(&trace[i].event()); - let second_name = name_extractor(&trace[i + 1].event()); + let first_name = name_extractor(trace[i].event()); + let second_name = name_extractor(trace[i + 1].event()); *df_relations.entry((Some(first_name), Some(second_name))).or_insert(0) += 1usize; } @@ -301,7 +301,7 @@ pub fn adjust_connections( let to_name = graph.node(edge.to_node()).unwrap().data().cloned(); let edge_key = (*edge.from_node(), *edge.to_node()); - if df_relations.get(&(from_name, to_name)).is_none() { + if !df_relations.contains_key(&(from_name, to_name)) { nodes_to_disconnect.push(edge_key) } } @@ -315,7 +315,7 @@ pub fn adjust_weights( log: &Vec>>, graph: &mut DefaultGraph, start_node_id: u64, -) -> Result<(), DiscoverRootSequenceGraphError> { +) -> Result<(), DiscoverECFGError> { let mut edges_weights = HashMap::new(); for trace in log { let replay_history = replay_sequence_with_history(graph, start_node_id, &trace[1..])?; @@ -334,7 +334,7 @@ pub fn adjust_weights( Ok(()) } -pub fn find_next_node(graph: &DefaultGraph, current_node: u64, next_event_id: u64) -> Result { +pub fn find_next_node(graph: &DefaultGraph, current_node: u64, next_event_id: u64) -> Result { let next_nodes = graph .outgoing_nodes(¤t_node) .into_iter() @@ -354,7 +354,7 @@ pub fn find_next_node(graph: &DefaultGraph, current_node: u64, next_event_id: u6 .collect::>(); if next_nodes.len() != 1 { - Err(DiscoverRootSequenceGraphError::NotSingleCandidateForNextNode) + Err(DiscoverECFGError::NotSingleCandidateForNextNode) } else { Ok(*next_nodes.first().unwrap()) } @@ -365,7 +365,7 @@ pub fn adjust_edges_data( log: &Vec>>, graph: &mut DefaultGraph, start_node_id: u64, -) -> Result<(), DiscoverRootSequenceGraphError> { +) -> Result<(), DiscoverECFGError> { for trace in log { let replay_history = replay_sequence_with_history(graph, start_node_id, &trace[1..])?; diff --git a/Ficus/src/rust/ficus/src/features/discovery/root_sequence/context.rs b/Ficus/src/rust/ficus/src/features/discovery/ecfg/context.rs similarity index 95% rename from Ficus/src/rust/ficus/src/features/discovery/root_sequence/context.rs rename to Ficus/src/rust/ficus/src/features/discovery/ecfg/context.rs index 2b76c29f5..8689346de 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/root_sequence/context.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/ecfg/context.rs @@ -1,12 +1,12 @@ use crate::{ - features::discovery::root_sequence::models::RootSequenceKind, + features::discovery::ecfg::models::RootSequenceKind, utils::{references::HeapedOrOwned, user_data::user_data::UserDataImpl}, }; type NameExtractor<'a, T> = &'a dyn Fn(&T) -> HeapedOrOwned; type ArtificialStartEnd<'a, T> = &'a dyn Fn() -> (T, T); -type NodeDataTransfer<'a, T> = &'a dyn Fn(&T, &mut UserDataImpl, bool) -> (); -type EdgeDataTransfer<'a, T> = &'a dyn Fn(&T, &mut UserDataImpl) -> (); +type NodeDataTransfer<'a, T> = &'a dyn Fn(&T, &mut UserDataImpl, bool); +type EdgeDataTransfer<'a, T> = &'a dyn Fn(&T, &mut UserDataImpl); pub struct DiscoveryContext<'a, T> { name_extractor: NameExtractor<'a, T>, diff --git a/Ficus/src/rust/ficus/src/features/discovery/root_sequence/context_keys.rs b/Ficus/src/rust/ficus/src/features/discovery/ecfg/context_keys.rs similarity index 56% rename from Ficus/src/rust/ficus/src/features/discovery/root_sequence/context_keys.rs rename to Ficus/src/rust/ficus/src/features/discovery/ecfg/context_keys.rs index 7c5c4d2d3..760283875 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/root_sequence/context_keys.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/ecfg/context_keys.rs @@ -4,7 +4,7 @@ use crate::{ features::{ analysis::patterns::pattern_info::{UnderlyingPatternGraphInfo, UnderlyingPatternInfo}, discovery::{ - root_sequence::models::{ActivityStartEndTimeData, CorrespondingTraceData, EdgeTraceExecutionInfo, NodeAdditionalDataContainer}, + ecfg::models::{ActivityStartEndTimeData, CorrespondingTraceData, EdgeTraceExecutionInfo, NodeAdditionalDataContainer}, timeline::software_data::models::SoftwareData, }, }, @@ -12,14 +12,14 @@ use crate::{ }; use lazy_static::lazy_static; -pub const NODE_SOFTWARE_DATA: &'static str = "node_software_data"; -pub const NODE_CORRESPONDING_TRACE_DATA: &'static str = "node_corresponding_trace_data"; -pub const NODE_INNER_GRAPH: &'static str = "node_inner_graph"; -pub const NODE_START_END_ACTIVITY_TIME: &'static str = "node_start_end_activity_time"; -pub const NODE_START_END_ACTIVITIES_TIMES: &'static str = "node_start_end_activities_times"; -pub const NODE_UNDERLYING_PATTERNS_INFOS: &'static str = "node_underlying_patterns_infos"; -pub const NODE_UNDERLYING_PATTERNS_GRAPHS_INFO: &'static str = "node_underlying_patterns_graphs_infos"; -pub const NODE_MULTITHREADED_FRAGMENT_LOG: &'static str = "node_multithreaded_fragment_log"; +pub const NODE_SOFTWARE_DATA: &str = "node_software_data"; +pub const NODE_CORRESPONDING_TRACE_DATA: &str = "node_corresponding_trace_data"; +pub const NODE_INNER_GRAPH: &str = "node_inner_graph"; +pub const NODE_START_END_ACTIVITY_TIME: &str = "node_start_end_activity_time"; +pub const NODE_START_END_ACTIVITIES_TIMES: &str = "node_start_end_activities_times"; +pub const NODE_UNDERLYING_PATTERNS_INFOS: &str = "node_underlying_patterns_infos"; +pub const NODE_UNDERLYING_PATTERNS_GRAPHS_INFO: &str = "node_underlying_patterns_graphs_infos"; +pub const NODE_MULTITHREADED_FRAGMENT_LOG: &str = "node_multithreaded_fragment_log"; context_key! { NODE_SOFTWARE_DATA, Vec> } context_key! { NODE_CORRESPONDING_TRACE_DATA, Vec> } @@ -30,9 +30,9 @@ context_key! { NODE_UNDERLYING_PATTERNS_INFOS, Vec> } context_key! { NODE_MULTITHREADED_FRAGMENT_LOG, Vec> } -pub const EDGE_SOFTWARE_DATA: &'static str = "edge_software_data"; -pub const EDGE_START_END_ACTIVITIES_TIMES: &'static str = "edge_start_end_activities_times"; -pub const EDGE_TRACE_EXECUTION_INFO: &'static str = "edge_trace_execution_info"; +pub const EDGE_SOFTWARE_DATA: &str = "edge_software_data"; +pub const EDGE_START_END_ACTIVITIES_TIMES: &str = "edge_start_end_activities_times"; +pub const EDGE_TRACE_EXECUTION_INFO: &str = "edge_trace_execution_info"; context_key! { EDGE_SOFTWARE_DATA, Vec } context_key! { EDGE_START_END_ACTIVITIES_TIMES, Vec } diff --git a/Ficus/src/rust/ficus/src/features/discovery/root_sequence/discovery.rs b/Ficus/src/rust/ficus/src/features/discovery/ecfg/discovery.rs similarity index 87% rename from Ficus/src/rust/ficus/src/features/discovery/root_sequence/discovery.rs rename to Ficus/src/rust/ficus/src/features/discovery/ecfg/discovery.rs index 6d59502b7..40e59713c 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/root_sequence/discovery.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/ecfg/discovery.rs @@ -1,13 +1,13 @@ use crate::{ context_key, features::discovery::{ - petri_net::annotations::PerformanceMap, - root_sequence::{ + ecfg::{ adjustments::{adjust_connections, adjust_edges_data, adjust_weights, find_next_node, merge_sequences_of_nodes}, context::DiscoveryContext, - models::{DiscoverRootSequenceGraphError, EventWithUniqueId, RootSequenceKind}, + models::{DiscoverECFGError, EventWithUniqueId, RootSequenceKind}, root_sequence::discover_root_sequence, }, + petri_net::annotations::PerformanceMap, }, utils::{ graph::{ @@ -26,17 +26,17 @@ use std::{ fmt::Debug, }; -const EVENT_UNIQUE_ID: &'static str = "EVENT_UNIQUE_ID"; +const EVENT_UNIQUE_ID: &str = "EVENT_UNIQUE_ID"; context_key! { EVENT_UNIQUE_ID, Vec } #[derive(Debug)] -pub struct RootSequenceGraphDiscoveryResult { +pub struct ECFGDiscoveryResult { graph: DefaultGraph, start_node_id: Option, end_node_id: Option, } -impl RootSequenceGraphDiscoveryResult { +impl ECFGDiscoveryResult { pub fn new(graph: DefaultGraph, start_node_id: Option, end_node_id: Option) -> Self { Self { graph, @@ -58,21 +58,21 @@ impl RootSequenceGraphDiscoveryResult { } pub fn start_node_id(&self) -> Option { - self.start_node_id.clone() + self.start_node_id } pub fn end_node_id(&self) -> Option { - self.end_node_id.clone() + self.end_node_id } } -pub fn discover_root_sequence_graph( +pub fn discover_ecfg( log: &Vec>>, context: &DiscoveryContext, merge_sequences_of_events: bool, performance_map: Option, -) -> Result { - let mut result = discover_root_sequence_graph_internal(log, context, true)?; +) -> Result { + let mut result = discover_ecfg_internal(log, context, true)?; let graph_kind = match context.root_sequence_kind() { RootSequenceKind::FindBest | RootSequenceKind::PairwiseLCS | RootSequenceKind::Trace => GraphKind::Dag, @@ -96,7 +96,7 @@ pub fn discover_root_sequence_graph( Ok(result) } -fn add_start_end_nodes_ids_to_user_data(result: &mut RootSequenceGraphDiscoveryResult) { +fn add_start_end_nodes_ids_to_user_data(result: &mut ECFGDiscoveryResult) { if let Some(start_node_id) = result.start_node_id() { result.graph.user_data_mut().put_concrete(START_NODE_ID_KEY.key(), start_node_id); } @@ -106,11 +106,11 @@ fn add_start_end_nodes_ids_to_user_data(result: &mut RootSequenceGraphDiscoveryR } } -fn discover_root_sequence_graph_internal( +fn discover_ecfg_internal( log: &Vec>>, context: &DiscoveryContext, first_iteration: bool, -) -> Result { +) -> Result { let root_sequence = discover_root_sequence(log, context.root_sequence_kind()); if root_sequence.len() == 2 { @@ -118,11 +118,11 @@ fn discover_root_sequence_graph_internal( } let mut graph = DefaultGraph::empty(); - let root_sequence_nodes_ids = initialize_lcs_graph_with_root_sequence(log, &root_sequence, &mut graph, &context, first_iteration); + let root_sequence_nodes_ids = initialize_lcs_graph_with_root_sequence(log, &root_sequence, &mut graph, context, first_iteration); adjust_lcs_graph_with_traces(log, &root_sequence, &root_sequence_nodes_ids, &mut graph, context)?; - Ok(RootSequenceGraphDiscoveryResult::new( + Ok(ECFGDiscoveryResult::new( graph, root_sequence_nodes_ids.first().cloned(), root_sequence_nodes_ids.last().cloned(), @@ -131,9 +131,9 @@ fn discover_root_sequence_graph_internal( fn handle_recursion_exit_case( log: &Vec>>, - root_sequence: &Vec>, + root_sequence: &[EventWithUniqueId], context: &DiscoveryContext, -) -> RootSequenceGraphDiscoveryResult { +) -> ECFGDiscoveryResult { let mut graph = DefaultGraph::empty(); let start_node = create_new_graph_node(&mut graph, root_sequence.first().unwrap(), false, context, false); @@ -155,7 +155,7 @@ fn handle_recursion_exit_case( graph.connect_nodes(&prev_node_id, &end_node, NodesConnectionData::empty()); } - RootSequenceGraphDiscoveryResult::new(graph, Some(start_node), Some(end_node)) + ECFGDiscoveryResult::new(graph, Some(start_node), Some(end_node)) } pub(super) fn create_new_graph_node( @@ -182,11 +182,11 @@ fn transfer_user_data( is_root_sequence: bool, context: &DiscoveryContext, ) { - let mut node = graph.node_mut(&node_id).unwrap(); + let node = graph.node_mut(&node_id).unwrap(); let transfer = context.event_to_graph_node_info_transfer(); transfer(event.event(), node.user_data_mut(), is_root_sequence); - transfer_unique_event_id(&mut node, event); + transfer_unique_event_id(node, event); } fn transfer_unique_event_id(node: &mut GraphNode>, event: &EventWithUniqueId) { @@ -238,13 +238,13 @@ fn initialize_lcs_graph_with_root_sequence( fn adjust_lcs_graph_with_traces( traces: &Vec>>, root_sequence: &Vec>, - root_sequence_node_ids: &Vec, + root_sequence_node_ids: &[u64], graph: &mut DefaultGraph, context: &DiscoveryContext, -) -> Result<(), DiscoverRootSequenceGraphError> { +) -> Result<(), DiscoverECFGError> { let mut adjustments = HashMap::new(); for trace in traces { - let trace_lcs = find_longest_common_subsequence(trace, &root_sequence, trace.len(), root_sequence.len()); + let trace_lcs = find_longest_common_subsequence(trace, root_sequence, trace.len(), root_sequence.len()); let second_indices = trace_lcs.second_indices(); let mut lcs_index = 0; @@ -301,13 +301,13 @@ fn adjust_lcs_graph_with_traces( } fn add_adjustments_to_graph( - adjustments: &Vec<(u64, Vec<(u64, Vec>>)>)>, + adjustments: &[(u64, Vec<(u64, Vec>>)>)], graph: &mut DefaultGraph, context: &DiscoveryContext, -) -> Result<(), DiscoverRootSequenceGraphError> { +) -> Result<(), DiscoverECFGError> { for (start_root_node_id, adjustments) in adjustments { let adjustment_log = create_log_from_adjustments(adjustments, context.artificial_start_end_events_factory()); - let result = discover_root_sequence_graph_internal(&adjustment_log, context, false)?; + let result = discover_ecfg_internal(&adjustment_log, context, false)?; merge_subgraph_into_model(adjustments, graph, result.graph_move(), *start_root_node_id, context)?; } @@ -371,7 +371,7 @@ fn merge_subgraph_into_model( sub_graph: DefaultGraph, start_graph_node_id: u64, context: &DiscoveryContext, -) -> Result<(), DiscoverRootSequenceGraphError> { +) -> Result<(), DiscoverECFGError> { let (start_node_id, end_node_id) = find_start_end_node_ids(&sub_graph, context.name_extractor(), context.artificial_start_end_events_factory()); let mut sub_graph_nodes_to_nodes = HashMap::new(); @@ -411,12 +411,12 @@ fn replay_sequence( graph: &DefaultGraph, start_node_id: u64, sequence: &[EventWithUniqueId], -) -> Result { +) -> Result { let mut replay_states = VecDeque::from_iter([(start_node_id, 0usize)]); loop { if replay_states.is_empty() { - return Err(DiscoverRootSequenceGraphError::FailedToReplaySequence); + return Err(DiscoverECFGError::FailedToReplaySequence); } let (current_node_id, event_index) = replay_states.pop_back().unwrap(); @@ -444,13 +444,13 @@ pub(super) fn replay_sequence_with_history( graph: &DefaultGraph, start_node_id: u64, sequence: &[EventWithUniqueId], -) -> Result, DiscoverRootSequenceGraphError> { +) -> Result, DiscoverECFGError> { let mut replay_states = VecDeque::from_iter([(start_node_id, 0usize, 0usize)]); let mut replay_history = vec![ReplayHistoryEntry::new(start_node_id, None)]; loop { if replay_states.is_empty() { - return Err(DiscoverRootSequenceGraphError::FailedToReplaySequence); + return Err(DiscoverECFGError::FailedToReplaySequence); } let (current_node_id, event_index, history_end_index) = replay_states.pop_back().unwrap(); diff --git a/Ficus/src/rust/ficus/src/features/discovery/root_sequence/discovery_xes.rs b/Ficus/src/rust/ficus/src/features/discovery/ecfg/discovery_xes.rs similarity index 87% rename from Ficus/src/rust/ficus/src/features/discovery/root_sequence/discovery_xes.rs rename to Ficus/src/rust/ficus/src/features/discovery/ecfg/discovery_xes.rs index 288a0c0c9..0940666b6 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/root_sequence/discovery_xes.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/ecfg/discovery_xes.rs @@ -6,23 +6,22 @@ use crate::{ features::{ analysis::patterns::{ activity_instances::{create_vector_of_underlying_events, try_get_base_pattern}, - pattern_info::{UnderlyingPatternGraphInfo, UnderlyingPatternInfo, UNDERLYING_PATTERN_KIND_KEY}, + pattern_info::{UNDERLYING_PATTERN_KIND_KEY, UnderlyingPatternGraphInfo, UnderlyingPatternInfo}, }, discovery::{ - petri_net::annotations::create_performance_map, - root_sequence::{ + ecfg::{ context::DiscoveryContext, context_keys::{ EDGE_SOFTWARE_DATA_KEY, EDGE_START_END_ACTIVITIES_TIMES_KEY, EDGE_TRACE_EXECUTION_INFO_KEY, NODE_CORRESPONDING_TRACE_DATA_KEY, NODE_MULTITHREADED_FRAGMENT_LOG_KEY, NODE_SOFTWARE_DATA_KEY, NODE_START_END_ACTIVITIES_TIMES_KEY, NODE_UNDERLYING_PATTERNS_GRAPHS_INFO_KEY, NODE_UNDERLYING_PATTERNS_INFOS_KEY, }, - discovery::{create_new_graph_node, discover_root_sequence_graph}, + discovery::{create_new_graph_node, discover_ecfg}, models::{ - CorrespondingTraceData, DiscoverRootSequenceGraphError, EventCoordinates, EventWithUniqueId, NodeAdditionalDataContainer, - RootSequenceKind, + CorrespondingTraceData, DiscoverECFGError, EventCoordinates, EventWithUniqueId, NodeAdditionalDataContainer, RootSequenceKind, }, }, + petri_net::annotations::create_performance_map, }, mutations::mutations::{ARTIFICIAL_END_EVENT_NAME, ARTIFICIAL_START_EVENT_NAME}, }, @@ -35,11 +34,11 @@ use crate::{ }; use std::{cell::RefCell, fmt::Debug, ops::Deref, rc::Rc}; -pub fn discover_root_sequence_graph_from_event_log( +pub fn discover_ecfg_from_event_log( log: &XesEventLogImpl, root_sequence_kind: RootSequenceKind, merge_sequences_of_events: bool, -) -> Result { +) -> Result { assert_all_traces_have_artificial_start_end_events(log)?; adjust_log_user_data(log); @@ -78,10 +77,10 @@ pub fn discover_root_sequence_graph_from_event_log( let log = log .into_iter() - .map(|t| t.into_iter().map(|e| EventWithUniqueId::new(e)).collect()) + .map(|t| t.into_iter().map(EventWithUniqueId::new).collect()) .collect(); - let mut result = discover_root_sequence_graph(&log, &context, merge_sequences_of_events, Some(performance_map))?; + let mut result = discover_ecfg(&log, &context, merge_sequences_of_events, Some(performance_map))?; discover_graphs_for_patterns(result.graph_mut(), &context); Ok(result.graph_move()) @@ -157,7 +156,7 @@ fn discover_graphs_for_patterns(graph: &mut DefaultGraph, context: &DiscoveryCon let mut pattern_graph_infos = vec![]; if let Some(patterns) = user_data.concrete(NODE_UNDERLYING_PATTERNS_INFOS_KEY.key()).cloned() { - if patterns.len() == 0 { + if patterns.is_empty() { continue; } @@ -175,15 +174,13 @@ fn discover_graphs_for_patterns(graph: &mut DefaultGraph, context: &DiscoveryCon prev_node_id = Some(current_node_id); } - let graph = Rc::new(Box::new(graph)); - - let base_sequence = match pattern.value().base_pattern() { - None => None, - Some(base_pattern) => Some(base_pattern.iter().map(|e| e.borrow().name().to_owned()).collect()), - }; + let base_sequence = pattern + .value() + .base_pattern() + .map(|base_pattern| base_pattern.iter().map(|e| e.borrow().name().to_owned()).collect()); - let pattern_graph_info = UnderlyingPatternGraphInfo::new(pattern.value().pattern_kind().clone(), base_sequence, graph); - let pattern_graph_info = NodeAdditionalDataContainer::new(pattern_graph_info, pattern.original_event_coordinates().clone()); + let pattern_graph_info = UnderlyingPatternGraphInfo::new(*pattern.value().pattern_kind(), base_sequence, graph); + let pattern_graph_info = NodeAdditionalDataContainer::new(pattern_graph_info, *pattern.original_event_coordinates()); pattern_graph_infos.push(pattern_graph_info); } @@ -200,7 +197,7 @@ fn transfer_vector_like_user_data( ) { if let Some(data) = event.borrow().user_data().concrete(key.key()) { if let Some(existing_data) = user_data_impl.concrete_mut(key.key()) { - existing_data.extend(data.clone().into_iter()); + existing_data.extend(data.clone()); } else { user_data_impl.put_concrete(key.key(), data.clone()); } @@ -234,10 +231,10 @@ fn adjust_event_coordinates( } } -fn assert_all_traces_have_artificial_start_end_events(log: &XesEventLogImpl) -> Result<(), DiscoverRootSequenceGraphError> { +fn assert_all_traces_have_artificial_start_end_events(log: &XesEventLogImpl) -> Result<(), DiscoverECFGError> { for trace in log.traces().iter().map(|t| t.borrow()) { if !check_trace_have_artificial_start_end_events(trace.deref()) { - return Err(DiscoverRootSequenceGraphError::NoArtificialStartEndEvents); + return Err(DiscoverECFGError::NoArtificialStartEndEvents); } } diff --git a/Ficus/src/rust/ficus/src/features/discovery/root_sequence/log_prepare.rs b/Ficus/src/rust/ficus/src/features/discovery/ecfg/log_prepare.rs similarity index 90% rename from Ficus/src/rust/ficus/src/features/discovery/root_sequence/log_prepare.rs rename to Ficus/src/rust/ficus/src/features/discovery/ecfg/log_prepare.rs index 613baa51b..be77d9998 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/root_sequence/log_prepare.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/ecfg/log_prepare.rs @@ -15,7 +15,7 @@ pub fn prepare_software_log( config: &SoftwareDataExtractionConfig, time_attribute: Option<&String>, ) -> Result { - let control_flow_regexes = config.control_flow_regexes().map_err(|e| PipelinePartExecutionError::new_raw(e))?; + let control_flow_regexes = config.control_flow_regexes().map_err(PipelinePartExecutionError::new_raw)?; if control_flow_regexes.is_none() { return Ok(log.clone()); } @@ -62,9 +62,7 @@ pub fn prepare_software_log( }; if index + 1 < last_stamp_index { - group.set_after_group_events(Some( - trace.events()[index + 1..last_stamp_index].iter().map(|e| e.clone()).collect(), - )); + group.set_after_group_events(Some(trace.events()[index + 1..last_stamp_index].to_vec())); } } @@ -100,5 +98,5 @@ pub fn prepare_software_log( } } - Ok(abstract_event_groups(event_groups, &labels, None, time_attribute.cloned(), config)?) + abstract_event_groups(event_groups, &labels, None, time_attribute.cloned(), config) } diff --git a/Ficus/src/rust/ficus/src/features/discovery/root_sequence/mod.rs b/Ficus/src/rust/ficus/src/features/discovery/ecfg/mod.rs similarity index 100% rename from Ficus/src/rust/ficus/src/features/discovery/root_sequence/mod.rs rename to Ficus/src/rust/ficus/src/features/discovery/ecfg/mod.rs diff --git a/Ficus/src/rust/ficus/src/features/discovery/root_sequence/models.rs b/Ficus/src/rust/ficus/src/features/discovery/ecfg/models.rs similarity index 84% rename from Ficus/src/rust/ficus/src/features/discovery/root_sequence/models.rs rename to Ficus/src/rust/ficus/src/features/discovery/ecfg/models.rs index fd02d2146..f75792556 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/root_sequence/models.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/ecfg/models.rs @@ -7,7 +7,7 @@ use std::{ }; #[derive(Debug)] -pub enum DiscoverRootSequenceGraphError { +pub enum DiscoverECFGError { NoArtificialStartEndEvents, FailedToReplaySequence, NotSingleCandidateForNextNode, @@ -35,16 +35,12 @@ impl FromStr for RootSequenceKind { } } -impl Display for DiscoverRootSequenceGraphError { +impl Display for DiscoverECFGError { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { - DiscoverRootSequenceGraphError::NoArtificialStartEndEvents => { - f.write_str("All traces in event log must have artificial start-end events") - } - DiscoverRootSequenceGraphError::FailedToReplaySequence => f.write_str("Failed to replay sequence of events on part of a graph"), - DiscoverRootSequenceGraphError::NotSingleCandidateForNextNode => { - f.write_str("There were several or zero candidates for next node during replay") - } + DiscoverECFGError::NoArtificialStartEndEvents => f.write_str("All traces in event log must have artificial start-end events"), + DiscoverECFGError::FailedToReplaySequence => f.write_str("Failed to replay sequence of events on part of a graph"), + DiscoverECFGError::NotSingleCandidateForNextNode => f.write_str("There were several or zero candidates for next node during replay"), } } } diff --git a/Ficus/src/rust/ficus/src/features/discovery/root_sequence/root_sequence.rs b/Ficus/src/rust/ficus/src/features/discovery/ecfg/root_sequence.rs similarity index 86% rename from Ficus/src/rust/ficus/src/features/discovery/root_sequence/root_sequence.rs rename to Ficus/src/rust/ficus/src/features/discovery/ecfg/root_sequence.rs index 8dcf675d2..a26c25375 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/root_sequence/root_sequence.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/ecfg/root_sequence.rs @@ -1,5 +1,5 @@ use crate::{ - features::discovery::root_sequence::models::RootSequenceKind, + features::discovery::ecfg::models::RootSequenceKind, utils::{ distance::distance::calculate_lcs_distance, lcs::{find_longest_common_subsequence, find_longest_common_subsequence_length}, @@ -20,7 +20,7 @@ pub fn discover_root_sequence(log: &Vec>, r let min_distance = root_distance.min(root_pair_wise_lcs_distance).min(root_lcs_distance); if root_distance == min_distance { - log.get(root_trace_index).unwrap().iter().map(|c| c.clone()).collect() + log.get(root_trace_index).unwrap().to_vec() } else if root_pair_wise_lcs_distance == min_distance { create_root_sequence_from_lcs(log, indices) } else { @@ -29,16 +29,11 @@ pub fn discover_root_sequence(log: &Vec>, r } RootSequenceKind::LCS => find_lcs_candidate_for_root_sequence(log).0, RootSequenceKind::PairwiseLCS => create_root_sequence_from_lcs(log, find_traces_pairwise_lcs_candidate_for_root_sequence(log).0), - RootSequenceKind::Trace => log - .get(find_trace_candidate_for_root_sequence(log).0) - .unwrap() - .iter() - .map(|c| c.clone()) - .collect(), + RootSequenceKind::Trace => log.get(find_trace_candidate_for_root_sequence(log).0).unwrap().to_vec(), } } -fn find_trace_candidate_for_root_sequence(log: &Vec>) -> (usize, f64) { +fn find_trace_candidate_for_root_sequence(log: &[Vec]) -> (usize, f64) { let mut root_trace_index = 0; let mut root_distance = f64::MAX; for (index, trace_events) in log.iter().enumerate() { @@ -59,7 +54,7 @@ fn find_trace_candidate_for_root_sequence(log: &Ve (root_trace_index, root_distance) } -fn find_traces_pairwise_lcs_candidate_for_root_sequence(log: &Vec>) -> ((usize, usize), f64) { +fn find_traces_pairwise_lcs_candidate_for_root_sequence(log: &[Vec]) -> ((usize, usize), f64) { let mut root_lcs_distance = f64::MAX; let mut indices = (0, 0); for (first_index, first_trace) in log.iter().enumerate() { @@ -70,7 +65,7 @@ fn find_traces_pairwise_lcs_candidate_for_root_sequence>(); @@ -91,12 +86,12 @@ fn find_traces_pairwise_lcs_candidate_for_root_sequence(log: &Vec>) -> (Vec, f64) { - let mut lcs = log.first().unwrap().into_iter().map(|e| (*e).clone()).collect(); + let mut lcs = log.first().unwrap().iter().map(|e| (*e).clone()).collect::>(); for trace in log.iter().skip(1) { lcs = find_longest_common_subsequence(&lcs, trace, lcs.len(), trace.len()) .lcs() - .into_iter() + .iter() .map(|e| (*e).clone()) .collect(); } @@ -109,7 +104,7 @@ fn find_lcs_candidate_for_root_sequence(log: &Vec< (lcs, distance) } -fn create_root_sequence_from_lcs(log: &Vec>, indices: (usize, usize)) -> Vec { +fn create_root_sequence_from_lcs(log: &[Vec], indices: (usize, usize)) -> Vec { let first_trace = log.get(indices.0).unwrap(); let second_trace = log.get(indices.1).unwrap(); @@ -118,7 +113,7 @@ fn create_root_sequence_from_lcs(log: &Vec> find_longest_common_subsequence(first_trace, second_trace, first_trace_len, second_trace_len) .lcs() - .into_iter() + .iter() .map(|c| (*c).clone()) .collect::>() } diff --git a/Ficus/src/rust/ficus/src/features/discovery/fuzzy/fuzzy_metrics_provider.rs b/Ficus/src/rust/ficus/src/features/discovery/fuzzy/fuzzy_metrics_provider.rs index 994be7485..4c1241006 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/fuzzy/fuzzy_metrics_provider.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/fuzzy/fuzzy_metrics_provider.rs @@ -7,7 +7,7 @@ use crate::{ }, }; -const PROXIMITY_CORRELATION: &'static str = "ProximityCorrelation"; +const PROXIMITY_CORRELATION: &str = "ProximityCorrelation"; pub struct FuzzyMetricsProvider<'a, TLog> where @@ -59,31 +59,28 @@ where let name = event.name(); if name == first_class { - last_seen_first = Some(i.clone()); + last_seen_first = Some(i); continue; } - if name == second_class { - if let Some(first_index) = last_seen_first { - let second_stamp = event.timestamp(); - let first_event = events.get(first_index).unwrap(); - let first_event = first_event.borrow(); - let first_stamp = first_event.timestamp(); - - result += second_stamp.signed_duration_since(*first_stamp).num_milliseconds() as f64; - count += 1; - last_seen_first = None; - } + if name == second_class + && let Some(first_index) = last_seen_first + { + let second_stamp = event.timestamp(); + let first_event = events.get(first_index).unwrap(); + let first_event = first_event.borrow(); + let first_stamp = first_event.timestamp(); + + result += second_stamp.signed_duration_since(*first_stamp).num_milliseconds() as f64; + count += 1; + last_seen_first = None; } } } result = if count != 0 { result / (count as f64) } else { 0.0 }; - self - .caches - .cache_mut(PROXIMITY_CORRELATION) - .put(first_class, second_class, result.clone()); + self.caches.cache_mut(PROXIMITY_CORRELATION).put(first_class, second_class, result); result } diff --git a/Ficus/src/rust/ficus/src/features/discovery/fuzzy/fuzzy_miner.rs b/Ficus/src/rust/ficus/src/features/discovery/fuzzy/fuzzy_miner.rs index 9b0ef5d2e..770da33c8 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/fuzzy/fuzzy_miner.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/fuzzy/fuzzy_miner.rs @@ -86,9 +86,9 @@ fn resolve_conflicts( let first_id = classes_to_ids.get(first_name).unwrap(); let second_id = classes_to_ids.get(second_name).unwrap(); - if are_nodes_bi_connected(&graph, first_id, second_id) { - let first_second_sig = provider.relative_significance(first_name, second_name, &graph); - let second_first_sig = provider.relative_significance(second_name, first_name, &graph); + if are_nodes_bi_connected(graph, first_id, second_id) { + let first_second_sig = provider.relative_significance(first_name, second_name, graph); + let second_first_sig = provider.relative_significance(second_name, first_name, graph); if first_second_sig < preserve_threshold || second_first_sig < preserve_threshold { let offset = (first_second_sig - second_first_sig).abs(); @@ -126,11 +126,11 @@ fn filter_edges( } for (node_id, incoming_nodes_ids) in node_to_incoming_nodes { - if incoming_nodes_ids.len() == 0 { + if incoming_nodes_ids.is_empty() { continue; } - let incoming_nodes: Vec = incoming_nodes_ids.iter().map(|c| *c).collect(); + let incoming_nodes: Vec = incoming_nodes_ids.iter().copied().collect(); let mut utility_measures = vec![0.0; incoming_nodes.len()]; let second = graph.node(&node_id).unwrap().data().unwrap(); @@ -242,22 +242,20 @@ fn merge_nodes(graph: &mut FuzzyGraph, clusters: &ClustersMap) { for cluster in clusters.values() { let cluster = cluster.borrow(); graph.merge_nodes_into_one( - &cluster.set().iter().map(|id| *id).collect(), + &cluster.set().iter().copied().collect(), |nodes_data| { let mut cluster_data = String::new(); cluster_data.push_str("Cluster["); - for data in &nodes_data { - if let Some(data) = data { - cluster_data.push_str(data); - cluster_data.push(','); - } + for data in nodes_data.iter().flatten() { + cluster_data.push_str(data); + cluster_data.push(','); } if cluster_data.ends_with(',') { cluster_data.remove(cluster_data.len() - 1); } - cluster_data.push_str("]"); + cluster_data.push(']'); Some(cluster_data) }, @@ -337,11 +335,7 @@ fn clusters_correlation( } } - if count == 0 { - 0.0 - } else { - corr / count as f64 - } + if count == 0 { 0.0 } else { corr / count as f64 } } fn find_most_correlated_cluster( diff --git a/Ficus/src/rust/ficus/src/features/discovery/heuristic/heuristic_miner.rs b/Ficus/src/rust/ficus/src/features/discovery/heuristic/heuristic_miner.rs index e76f016cd..834be91f2 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/heuristic/heuristic_miner.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/heuristic/heuristic_miner.rs @@ -55,7 +55,7 @@ fn construct_heuristic_petri_net(provider: &HeuristicMinerRelationsProvider, pet } } - if followers.len() == 0 { + if followers.is_empty() { continue; } diff --git a/Ficus/src/rust/ficus/src/features/discovery/heuristic/relations_provider.rs b/Ficus/src/rust/ficus/src/features/discovery/heuristic/relations_provider.rs index 45e3517f2..0e784bb86 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/heuristic/relations_provider.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/heuristic/relations_provider.rs @@ -142,7 +142,7 @@ impl<'a> HeuristicMinerRelationsProvider<'a> { } fn triangle_occurrences_count(&self, first: &str, second: &str) -> usize { - self.triangle_relation.get(first, second).unwrap_or_else(|| 0) + self.triangle_relation.get(first, second).unwrap_or(0) } pub fn log_info(&self) -> &dyn EventLogInfo { diff --git a/Ficus/src/rust/ficus/src/features/discovery/mod.rs b/Ficus/src/rust/ficus/src/features/discovery/mod.rs index 2355b642b..a51b063de 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/mod.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/mod.rs @@ -1,9 +1,9 @@ pub mod alpha; +pub mod ecfg; pub mod fuzzy; pub mod heuristic; pub mod multithreaded_dfg; pub mod ocel; pub mod petri_net; pub mod relations; -pub mod root_sequence; pub mod timeline; diff --git a/Ficus/src/rust/ficus/src/features/discovery/multithreaded_dfg/dfg.rs b/Ficus/src/rust/ficus/src/features/discovery/multithreaded_dfg/dfg.rs index ebbd52488..2db53c256 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/multithreaded_dfg/dfg.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/multithreaded_dfg/dfg.rs @@ -21,7 +21,7 @@ use std::{ rc::Rc, }; -const MULTITHREADED_FRAGMENT: &'static str = "MULTITHREADED_FRAGMENT"; +const MULTITHREADED_FRAGMENT: &str = "MULTITHREADED_FRAGMENT"; context_key! { MULTITHREADED_FRAGMENT, XesEventLogImpl } @@ -117,10 +117,8 @@ pub fn enumerate_multithreaded_events_groups( last_group = Some(EventGroup::empty()); last_group.as_mut().unwrap().control_flow_events_mut().push(event.clone()); - } else { - if let Some(group) = last_group.as_mut() { - group.statistic_events_mut().push(event.clone()); - } + } else if let Some(group) = last_group.as_mut() { + group.statistic_events_mut().push(event.clone()); } } diff --git a/Ficus/src/rust/ficus/src/features/discovery/ocel/graph_annotation.rs b/Ficus/src/rust/ficus/src/features/discovery/ocel/graph_annotation.rs index 18431a1d0..a060ae9fc 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/ocel/graph_annotation.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/ocel/graph_annotation.rs @@ -1,5 +1,5 @@ use crate::{ - features::discovery::{root_sequence::context_keys::EDGE_SOFTWARE_DATA_KEY, timeline::software_data::models::OcelObjectAction}, + features::discovery::{ecfg::context_keys::EDGE_SOFTWARE_DATA_KEY, timeline::software_data::models::OcelObjectAction}, utils::{graph::graph::DefaultGraph, references::HeapedOrOwned, user_data::user_data::UserData}, }; use derive_new::new; @@ -26,17 +26,13 @@ pub enum OcelAnnotationCreationError { OneOfMergedObjetsDoesNotExist, } -#[derive(Getters)] +#[derive(Getters, Default)] pub struct NodeObjectsState { #[getset(get = "pub")] map: HashMap, HashSet>>, } impl NodeObjectsState { - pub fn new() -> Self { - Self { map: HashMap::new() } - } - pub fn add_allocated_object( &mut self, object_type: HeapedOrOwned, @@ -86,7 +82,7 @@ impl NodeObjectsState { pub fn add_state_from(&mut self, other: &NodeObjectsState) { for (obj_type, ids) in other.map.iter() { - let set = self.map.entry(obj_type.to_owned()).or_insert(HashSet::new()); + let set = self.map.entry(obj_type.to_owned()).or_default(); for id in ids { set.insert(id.clone()); @@ -116,7 +112,7 @@ pub struct OcelObjectRelations { } lazy_static! { - pub static ref UNKNOWN_TYPE: Box = Box::new("UNKNOWN".to_string()); + pub static ref UNKNOWN_TYPE: String = "UNKNOWN".to_string(); } pub fn create_ocel_annotation_for_dag(graph: &DefaultGraph) -> Result { @@ -131,7 +127,7 @@ pub fn create_ocel_annotation_for_dag(graph: &DefaultGraph) -> Result Result Result Option> { let replay_states = replay_petri_net(log, net); - if replay_states.is_none() { - return None; - } + replay_states.as_ref()?; let mut fired_arcs = HashMap::new(); for state in replay_states.as_ref().unwrap() { @@ -57,7 +55,7 @@ pub fn annotate_with_frequencies( let count_annotation = annotate_with_counts(log, net, terminate_on_unreplayable_trace)?; let mut freq_annotations = HashMap::new(); - let sum: usize = count_annotation.values().into_iter().sum(); + let sum: usize = count_annotation.values().sum(); for (arc_id, count) in count_annotation { freq_annotations.insert(arc_id, (count as f64) / sum as f64); } @@ -102,7 +100,7 @@ pub enum PerformanceAnnotationInfo { SumAndCount(f64, usize), } -const PERFORMANCE_ANNOTATION_INFO: &'static str = "PERFORMANCE_ANNOTATION_INFO"; +const PERFORMANCE_ANNOTATION_INFO: &str = "PERFORMANCE_ANNOTATION_INFO"; context_key! { PERFORMANCE_ANNOTATION_INFO, PerformanceAnnotationInfo } pub type PerformanceMap = HashMap<(HeapedOrOwned, HeapedOrOwned), (f64, usize)>; @@ -143,11 +141,7 @@ pub fn create_performance_map(log: &impl EventLog) -> PerformanceMap { performance_map } -pub fn annotate_with_time_performance( - log: &impl EventLog, - graph: &DefaultGraph, - annotation_kind: TimeAnnotationKind, -) -> Option> { +pub fn annotate_with_time_performance(log: &impl EventLog, graph: &DefaultGraph, kind: TimeAnnotationKind) -> Option> { let performance_map = create_performance_map(log); let mut time_annotations = HashMap::new(); @@ -157,22 +151,20 @@ pub fn annotate_with_time_performance( let annotation = if let Some(performance_data) = edge.user_data().concrete(PERFORMANCE_ANNOTATION_INFO_KEY.key()) { Some(match performance_data { - PerformanceAnnotationInfo::Default(data) => match annotation_kind { + PerformanceAnnotationInfo::Default(data) => match kind { TimeAnnotationKind::SummedTime => data.iter().sum(), TimeAnnotationKind::Mean => data.iter().sum::() / data.len() as f64, }, - PerformanceAnnotationInfo::SumAndCount(sum, count) => match annotation_kind { + PerformanceAnnotationInfo::SumAndCount(sum, count) => match kind { TimeAnnotationKind::SummedTime => *sum, TimeAnnotationKind::Mean => *sum / (*count as f64), }, }) - } else if let Some(time_annotation) = try_get_time_annotation(&performance_map, first_node, second_node) { - Some(match annotation_kind { + } else { + try_get_time_annotation(&performance_map, first_node, second_node).map(|time_annotation| match kind { TimeAnnotationKind::SummedTime => time_annotation.0, TimeAnnotationKind::Mean => time_annotation.0 / time_annotation.1 as f64, }) - } else { - None }; if let Some(annotation) = annotation { @@ -195,7 +187,7 @@ fn try_get_time_annotation( ); if let Some(time_annotation) = performance_map.get(&key) { - return Some(time_annotation.clone()); + return Some(*time_annotation); } } diff --git a/Ficus/src/rust/ficus/src/features/discovery/petri_net/petri_net.rs b/Ficus/src/rust/ficus/src/features/discovery/petri_net/petri_net.rs index bc3e859a0..4155417de 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/petri_net/petri_net.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/petri_net/petri_net.rs @@ -53,11 +53,11 @@ where } pub fn all_places(&self) -> Vec<&Place> { - self.places.values().into_iter().collect() + self.places.values().collect() } pub fn all_transitions(&self) -> Vec<&Transition> { - self.transitions.values().into_iter().collect() + self.transitions.values().collect() } pub fn delete_transition(&mut self, id: &u64) -> Option> { @@ -73,7 +73,7 @@ where pub fn connect_place_to_transition(&mut self, from_place_id: &u64, to_transition_index: &u64, arc_data: Option) { self .transitions - .get_mut(&to_transition_index) + .get_mut(to_transition_index) .unwrap() .add_incoming_arc(from_place_id, arc_data); @@ -95,7 +95,7 @@ where pub fn connect_transition_to_place(&mut self, from_transition_id: &u64, to_place_id: &u64, arc_data: Option) { self .transitions - .get_mut(&from_transition_id) + .get_mut(from_transition_id) .unwrap() .add_outgoing_arc(to_place_id, arc_data); @@ -143,13 +143,7 @@ where } pub fn find_transition_by_name(&self, name: &str) -> Option<&Transition> { - for transition in self.transitions.values() { - if transition.name() == name { - return Some(transition); - } - } - - None + self.transitions.values().find(|&transition| transition.name() == name) } pub fn find_all_transitions_by_name(&self, name: &str) -> Option>> { @@ -160,11 +154,7 @@ where } } - if result.is_empty() { - None - } else { - Some(result) - } + if result.is_empty() { None } else { Some(result) } } pub fn arc(&self, id: &u64) -> Option<(&Arc, &Transition)> { @@ -193,7 +183,7 @@ where self.places_to_transitions.get(place_id).unwrap() } - fn map_transitions(&self, ids: &Vec) -> Vec<&Transition> { + fn map_transitions(&self, ids: &[u64]) -> Vec<&Transition> { ids.iter().map(|id| self.transitions.get(id).unwrap()).collect() } diff --git a/Ficus/src/rust/ficus/src/features/discovery/petri_net/place.rs b/Ficus/src/rust/ficus/src/features/discovery/petri_net/place.rs index d68548f5d..31062a93e 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/petri_net/place.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/petri_net/place.rs @@ -1,6 +1,6 @@ use crate::{features::discovery::petri_net::ids::next_id, utils::user_data::user_data::UserDataImpl}; -const EMPTY_PLACE_NAME: &'static str = "EmptyPlace"; +const EMPTY_PLACE_NAME: &str = "EmptyPlace"; #[derive(Debug)] pub struct Place { @@ -14,7 +14,7 @@ impl Place { Self { id: next_id(), name: EMPTY_PLACE_NAME.to_owned(), - user_data: UserDataImpl::new(), + user_data: Default::default(), } } @@ -22,7 +22,7 @@ impl Place { Self { id: next_id(), name, - user_data: UserDataImpl::new(), + user_data: Default::default(), } } diff --git a/Ficus/src/rust/ficus/src/features/discovery/petri_net/pnml_serialization.rs b/Ficus/src/rust/ficus/src/features/discovery/petri_net/pnml_serialization.rs index 317a45102..1e3429f97 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/petri_net/pnml_serialization.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/petri_net/pnml_serialization.rs @@ -3,22 +3,22 @@ use crate::{ utils::xml_utils::{StartEndElementCookie, XmlWriteError}, }; use quick_xml::{ - events::{BytesText, Event}, Writer, + events::{BytesText, Event}, }; use std::{cell::RefCell, fs, io::Cursor}; -const PNML_TAG_NAME: &'static str = "pnml"; -const TRANSITION_TAG_NAME: &'static str = "transition"; -const ARC_TAG_NAME: &'static str = "arc"; -const PLACE_TAG_NAME: &'static str = "place"; -const NET_TAG_NAME: &'static str = "net"; -const TEXT_TAG_NAME: &'static str = "text"; -const NAME_TAG_NAME: &'static str = "name"; +const PNML_TAG_NAME: &str = "pnml"; +const TRANSITION_TAG_NAME: &str = "transition"; +const ARC_TAG_NAME: &str = "arc"; +const PLACE_TAG_NAME: &str = "place"; +const NET_TAG_NAME: &str = "net"; +const TEXT_TAG_NAME: &str = "text"; +const NAME_TAG_NAME: &str = "name"; -const ID_ATTR_NAME: &'static str = "id"; -const SOURCE_ATTR_NAME: &'static str = "source"; -const TARGET_ATTR_NAME: &'static str = "target"; +const ID_ATTR_NAME: &str = "id"; +const SOURCE_ATTR_NAME: &str = "source"; +const TARGET_ATTR_NAME: &str = "target"; pub fn serialize_to_pnml_file( net: &PetriNet, @@ -95,14 +95,14 @@ where { for transition in created_ordered_transitions_list(net) { let cookie = StartEndElementCookie::new_with_attrs( - &writer, + writer, TRANSITION_TAG_NAME, &vec![(ID_ATTR_NAME, create_transition_id(transition, use_names_as_ids).as_str())], ); if let Some(data) = transition.data() { - let name = StartEndElementCookie::new(&writer, NAME_TAG_NAME); - let text = StartEndElementCookie::new(&writer, TEXT_TAG_NAME); + let name = StartEndElementCookie::new(writer, NAME_TAG_NAME); + let text = StartEndElementCookie::new(writer, TEXT_TAG_NAME); match writer .borrow_mut() @@ -168,7 +168,7 @@ where for arc in &incoming_arcs { StartEndElementCookie::new_with_attrs( - &writer, + writer, ARC_TAG_NAME, &vec![ (ID_ATTR_NAME, arc.1.as_str()), @@ -185,7 +185,7 @@ where } fn patch_arcs_list( - arcs: &Vec>, + arcs: &[Arc], use_names_as_ids: bool, names_creator: impl Fn(&Arc) -> String, ) -> Vec<(&Arc, String)> { @@ -224,7 +224,7 @@ where for arc in outgoing_arcs { StartEndElementCookie::new_with_attrs( - &writer, + writer, ARC_TAG_NAME, &vec![ (ID_ATTR_NAME, arc.1.as_str()), diff --git a/Ficus/src/rust/ficus/src/features/discovery/petri_net/replay.rs b/Ficus/src/rust/ficus/src/features/discovery/petri_net/replay.rs index c452f1e7b..b72c973ce 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/petri_net/replay.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/petri_net/replay.rs @@ -112,7 +112,7 @@ pub fn replay_petri_net(log: &impl EventLog, net: &DefaultPetriNet) -> Option Option { - if let Some(measure) = self.relations.get(&(first.to_owned(), second.to_owned())) { - Some(*measure) - } else { - None - } + self.relations.get(&(first.to_owned(), second.to_owned())).copied() } } diff --git a/Ficus/src/rust/ficus/src/features/discovery/timeline/abstraction.rs b/Ficus/src/rust/ficus/src/features/discovery/timeline/abstraction.rs index dfc9dbdb8..22125a939 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/timeline/abstraction.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/timeline/abstraction.rs @@ -4,14 +4,14 @@ use crate::{ xes::{xes_event::XesEventImpl, xes_event_log::XesEventLogImpl, xes_trace::XesTraceImpl}, }, features::discovery::{ - multithreaded_dfg::dfg::MULTITHREADED_FRAGMENT_KEY, - root_sequence::{ + ecfg::{ context_keys::{ EDGE_SOFTWARE_DATA_KEY, EDGE_START_END_ACTIVITIES_TIMES_KEY, EDGE_TRACE_EXECUTION_INFO_KEY, NODE_MULTITHREADED_FRAGMENT_LOG_KEY, NODE_SOFTWARE_DATA_KEY, NODE_START_END_ACTIVITIES_TIMES_KEY, }, models::{ActivityStartEndTimeData, EdgeTraceExecutionInfo, EventCoordinates, NodeAdditionalDataContainer}, }, + multithreaded_dfg::dfg::MULTITHREADED_FRAGMENT_KEY, timeline::{ events_groups::EventGroup, software_data::{ @@ -41,7 +41,7 @@ use std::{cell::RefCell, rc::Rc}; pub fn abstract_event_groups( event_groups: Vec>, - labels: &Vec, + labels: &[usize], thread_attribute: Option, time_attribute: Option, config: &SoftwareDataExtractionConfig, @@ -71,7 +71,7 @@ pub fn abstract_event_groups( let group_label = *labels.get(current_label_index).as_ref().unwrap(); let abstracted_event = create_abstracted_event( - &event_group, + event_group, group_label, thread_attribute.as_ref(), time_attribute.as_ref(), @@ -101,7 +101,7 @@ fn create_abstracted_event( mut node_software_data: SoftwareData, mut edge_software_data: SoftwareData, ) -> Result>, PipelinePartExecutionError> { - let first_stamp = event_group.control_flow_events().first().unwrap().borrow().timestamp().clone(); + let first_stamp = *event_group.control_flow_events().first().unwrap().borrow().timestamp(); let abstracted_event_stamp = *event_group.control_flow_events().last().unwrap().borrow().timestamp() - first_stamp; let abstracted_event_stamp = first_stamp + abstracted_event_stamp; @@ -130,10 +130,10 @@ fn create_abstracted_event( )?; } - if let Some(cf_event) = event_group.control_flow_events().first().as_ref() { - if let Some(display_name) = cf_event.borrow().user_data().concrete(DISPLAY_NAME_KEY.key()) { - event.user_data_mut().put_concrete(DISPLAY_NAME_KEY.key(), display_name.clone()); - } + if let Some(cf_event) = event_group.control_flow_events().first().as_ref() + && let Some(display_name) = cf_event.borrow().user_data().concrete(DISPLAY_NAME_KEY.key()) + { + event.user_data_mut().put_concrete(DISPLAY_NAME_KEY.key(), display_name.clone()); } Ok(Rc::new(RefCell::new(event))) @@ -151,8 +151,11 @@ fn put_node_user_data( .user_data_mut() .put_concrete(NODE_SOFTWARE_DATA_KEY.key(), vec![software_data]); - let first_stamp = get_stamp(&event_group.control_flow_events().first().unwrap().borrow(), time_attribute).map_err(|e| e.into())?; - let last_stamp = get_stamp(&event_group.control_flow_events().last().unwrap().borrow(), time_attribute).map_err(|e| e.into())?; + let first_stamp = + get_stamp(&event_group.control_flow_events().first().unwrap().borrow(), time_attribute).map_err(PipelinePartExecutionError::from)?; + + let last_stamp = + get_stamp(&event_group.control_flow_events().last().unwrap().borrow(), time_attribute).map_err(PipelinePartExecutionError::from)?; let activity_start_end_time = ActivityStartEndTimeData::new(first_stamp, last_stamp); let activity_start_end_time = NodeAdditionalDataContainer::new(activity_start_end_time, event_coordinates); @@ -175,15 +178,16 @@ fn put_edge_user_data( event: &mut XesEventImpl, edge_software_data: SoftwareData, event_coordinates: EventCoordinates, - after_group_events: &Vec>>, + after_group_events: &[Rc>], time_attribute: Option<&String>, ) -> Result<(), PipelinePartExecutionError> { event .user_data_mut() .put_concrete(EDGE_SOFTWARE_DATA_KEY.key(), vec![edge_software_data]); - let first_stamp = get_stamp(&after_group_events.first().unwrap().borrow(), time_attribute).map_err(|e| e.into())?; - let last_stamp = get_stamp(&after_group_events.last().unwrap().borrow(), time_attribute).map_err(|e| e.into())?; + let first_stamp = get_stamp(&after_group_events.first().unwrap().borrow(), time_attribute).map_err(PipelinePartExecutionError::from)?; + + let last_stamp = get_stamp(&after_group_events.last().unwrap().borrow(), time_attribute).map_err(PipelinePartExecutionError::from)?; let edge_start_end_time = ActivityStartEndTimeData::new(first_stamp, last_stamp); diff --git a/Ficus/src/rust/ficus/src/features/discovery/timeline/discovery.rs b/Ficus/src/rust/ficus/src/features/discovery/timeline/discovery.rs index 261643e89..6249baf7b 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/timeline/discovery.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/timeline/discovery.rs @@ -4,7 +4,7 @@ use crate::{ xes::{xes_event::XesEventImpl, xes_event_log::XesEventLogImpl}, }, features::discovery::timeline::{ - events_groups::{discover_events_groups, TraceEventsGroup}, + events_groups::{TraceEventsGroup, discover_events_groups}, utils::{extract_thread_id, get_stamp}, }, pipelines::errors::pipeline_errors::{PipelinePartExecutionError, RawPartExecutionError}, @@ -99,9 +99,9 @@ impl Display for LogThreadsDiagramError { impl Error for LogThreadsDiagramError {} -impl Into for LogThreadsDiagramError { - fn into(self) -> PipelinePartExecutionError { - PipelinePartExecutionError::Raw(RawPartExecutionError::new(self.to_string())) +impl From for PipelinePartExecutionError { + fn from(val: LogThreadsDiagramError) -> Self { + PipelinePartExecutionError::Raw(RawPartExecutionError::new(val.to_string())) } } @@ -151,10 +151,7 @@ pub fn discover_traces_timeline_diagram( control_flow_regexes: control_flow_regexes.cloned(), thread_attribute: "Trace".to_string(), traces: timeline_fragments, - time_attribute: match time_attribute { - None => None, - Some(s) => Some(s.to_owned()), - }, + time_attribute: time_attribute.map(|s| s.to_owned()), }) } @@ -212,7 +209,7 @@ pub fn discover_timeline_diagram( let events_groups = discover_events_groups_internal(&threads.values().collect(), event_group_delta, control_flow_regexes); traces.push(TraceTimelineDiagram { - threads: threads.into_iter().map(|(_, v)| v).collect(), + threads: threads.into_values().collect(), events_groups, }) } @@ -220,10 +217,7 @@ pub fn discover_timeline_diagram( Ok(LogTimelineDiagram { control_flow_regexes: control_flow_regexes.cloned(), thread_attribute: thread_attribute.to_string(), - time_attribute: match time_attribute { - None => None, - Some(s) => Some(s.to_owned()), - }, + time_attribute: time_attribute.map(|s| s.to_owned()), traces, }) } diff --git a/Ficus/src/rust/ficus/src/features/discovery/timeline/events_groups.rs b/Ficus/src/rust/ficus/src/features/discovery/timeline/events_groups.rs index b31bc3bee..76aaff25b 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/timeline/events_groups.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/timeline/events_groups.rs @@ -44,13 +44,12 @@ pub fn discover_events_groups( }; while let Some((event, trace_index, event_index)) = events.next() { - if let Some(control_flow_regexes) = control_flow_regexes { - if !control_flow_regexes + if let Some(control_flow_regexes) = control_flow_regexes + && !control_flow_regexes .iter() .any(|regex| regex.is_match(event.original_event().borrow().name()).unwrap_or(false)) - { - continue; - } + { + continue; } let create_events_group = || { @@ -60,9 +59,9 @@ pub fn discover_events_groups( }) }; - if last_stamp.is_some() { - if (*event.stamp() - last_stamp.unwrap()) as u64 > event_group_delta { - add_to_groups(last_trace_group.clone(), last_seen_point.clone()); + if let Some(last_stamp) = last_stamp { + if (*event.stamp() - last_stamp) as u64 > event_group_delta { + add_to_groups(last_trace_group.clone(), last_seen_point); last_trace_group = create_events_group(); } } else { @@ -70,10 +69,10 @@ pub fn discover_events_groups( } last_seen_point = Some((trace_index, event_index)); - last_stamp = Some(event.stamp().clone()); + last_stamp = Some(*event.stamp()); } - add_to_groups(last_trace_group.clone(), last_seen_point.clone()); + add_to_groups(last_trace_group.clone(), last_seen_point); groups } @@ -159,7 +158,7 @@ impl EventGroup { control_flow_events: vec![], statistic_events: vec![], after_group_events: None, - user_data: UserDataImpl::new(), + user_data: Default::default(), } } @@ -173,7 +172,7 @@ pub fn enumerate_event_groups(log: &LogTimelineDiagram) -> Vec> for trace_diagram in log.traces() { let mut group_index = 0; - let threads_refs: Vec<&TraceThread> = trace_diagram.threads().iter().map(|x| x).collect(); + let threads_refs: Vec<&TraceThread> = trace_diagram.threads().iter().collect(); let get_stamp = |point: &LogPoint| { threads_refs .get(*point.trace_index()) @@ -187,7 +186,7 @@ pub fn enumerate_event_groups(log: &LogTimelineDiagram) -> Vec> let mut events = ThreadsSequentialEvents::new(&threads_refs); let mut events_groups = trace_diagram.events_groups().clone(); - events_groups.sort_by(|f, s| get_stamp(f.start_point()).cmp(&get_stamp(s.start_point()))); + events_groups.sort_by(|f, s| get_stamp(f.start_point()).cmp(get_stamp(s.start_point()))); let mut trace_groups: Vec = vec![]; let mut current_group = None; diff --git a/Ficus/src/rust/ficus/src/features/discovery/timeline/software_data/extraction_config.rs b/Ficus/src/rust/ficus/src/features/discovery/timeline/software_data/extraction_config.rs index d17ae820a..220cfbc04 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/timeline/software_data/extraction_config.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/timeline/software_data/extraction_config.rs @@ -54,7 +54,7 @@ impl SoftwareDataExtractionConfig { match Regex::new(regex) { Ok(regex) => result.push(regex), Err(err) => { - return Err(format!("Failed to parse regex: error {}, raw regex {}", err.to_string(), regex)); + return Err(format!("Failed to parse regex: error {}, raw regex {}", err, regex)); } } } diff --git a/Ficus/src/rust/ficus/src/features/discovery/timeline/software_data/extractors/activities_durations.rs b/Ficus/src/rust/ficus/src/features/discovery/timeline/software_data/extractors/activities_durations.rs index e7e0fff7e..d74756762 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/timeline/software_data/extractors/activities_durations.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/timeline/software_data/extractors/activities_durations.rs @@ -39,7 +39,7 @@ impl<'a> EventGroupTraceSoftwareDataExtractor for ActivityDurationExtractor<'a> trace: &Vec, software_data: &mut Vec<(SoftwareData, SoftwareData)>, ) -> Result<(), SoftwareDataExtractionError> { - if self.config.activities_duration_configs().len() == 0 { + if self.config.activities_duration_configs().is_empty() { return Ok(()); } @@ -125,7 +125,7 @@ fn process_events_groups(trace: &Vec, configs: &mut Configs) -> Resu Ok(()) } -fn add_durations_to_software_data(configs: &Configs, software_data: &mut Vec<(SoftwareData, SoftwareData)>) { +fn add_durations_to_software_data(configs: &Configs, software_data: &mut [(SoftwareData, SoftwareData)]) { for (_, _, _, _, data) in configs { if data.len() != software_data.len() * 2 { error!("data.len() != result.len() * 2"); @@ -149,7 +149,7 @@ fn add_durations_to_software_data(configs: &Configs, software_data: &mut Vec<(So fn get_event_group_node_start_end_stamps( index: usize, - groups: &Vec, + groups: &[EventGroup], time_attr: Option<&TimeAttributeConfig>, ) -> Result<(i64, i64), SoftwareDataExtractionError> { Ok(( @@ -160,7 +160,7 @@ fn get_event_group_node_start_end_stamps( fn get_event_group_edge_start_end_stamps( index: usize, - groups: &Vec, + groups: &[EventGroup], time_attr: Option<&TimeAttributeConfig>, ) -> Result<(i64, i64), SoftwareDataExtractionError> { Ok(( @@ -229,7 +229,7 @@ impl DurationsMapExtensions for DurationsMap { return; } - (*self.entry(info.base().name().to_string()).or_insert((0u64, info.clone()))).0 += duration; + self.entry(info.base().name().to_string()).or_insert((0u64, info.clone())).0 += duration; } } @@ -266,11 +266,7 @@ fn process_events( Err(err) => return Err(err.clone()), }; - let id = if let Some(strategy) = info.activity_id_attr() { - Some(strategy.create(&event.borrow())) - } else { - None - }; + let id = info.activity_id_attr().as_ref().map(|strategy| strategy.create(&event.borrow())); if start_regex.is_match(event.borrow().name()).unwrap_or(false) { local_state.push(StackActivityStartEntry::new(id, (*event).clone())); @@ -290,7 +286,11 @@ fn process_events( for prev_data in previous_data.iter_mut() { if let Some(prev_data) = prev_data.as_mut() { let duration = (prev_data.end_time - prev_data.start_time) as u64; - (*prev_data.map.entry(info.base().name().to_string()).or_insert((0u64, info.clone()))).0 += duration; + prev_data + .map + .entry(info.base().name().to_string()) + .or_insert((0u64, info.clone())) + .0 += duration; } } } diff --git a/Ficus/src/rust/ficus/src/features/discovery/timeline/software_data/extractors/core.rs b/Ficus/src/rust/ficus/src/features/discovery/timeline/software_data/extractors/core.rs index 8d479ed82..2870cdcac 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/timeline/software_data/extractors/core.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/timeline/software_data/extractors/core.rs @@ -34,7 +34,7 @@ pub trait EventGroupSoftwareDataExtractor { let events = event_group .all_events() .into_iter() - .map(|c| c.clone()) + .cloned() .collect::>>>(); self.extract_from_events(software_data, events.as_slice()) diff --git a/Ficus/src/rust/ficus/src/features/discovery/timeline/software_data/extractors/ocel.rs b/Ficus/src/rust/ficus/src/features/discovery/timeline/software_data/extractors/ocel.rs index 10fcb90d4..022f14f72 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/timeline/software_data/extractors/ocel.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/timeline/software_data/extractors/ocel.rs @@ -84,7 +84,8 @@ impl<'a> OcelDataExtractor<'a> { } fn try_get_config<'b, T>(event: &'b XesEventImpl, config: Option<&'b (Regex, T)>) -> Option<&'b T> { - let Some((regex, config)) = config else { return None }; + let (regex, config) = config?; + if !regex.is_match(event.name().as_str()).unwrap_or(false) { return None; } @@ -117,7 +118,7 @@ impl<'a> OcelDataExtractor<'a> { ) -> Option<(HeapedOrOwned, HeapedOrOwned)> { let object_type = config.object_type_attr().create(event); - let object_id = match Self::parse_object_id(&event, config.object_id_attr().as_str()) { + let object_id = match Self::parse_object_id(event, config.object_id_attr().as_str()) { None => { debug!("Object does not have an object id, skipping it"); return None; @@ -166,7 +167,7 @@ impl<'a> OcelDataExtractor<'a> { }; let Some(payload) = event.payload_map() else { return false }; - let Some(object_id) = Self::parse_object_id(&event, config.object_id_attr().as_str()) else { + let Some(object_id) = Self::parse_object_id(event, config.object_id_attr().as_str()) else { return false; }; let related_objects_ids = Self::parse_related_objects_ids(payload, Some(config.related_object_ids_attr()), delimiter); @@ -186,7 +187,7 @@ impl<'a> OcelDataExtractor<'a> { let data = related_objects_ids .into_iter() - .zip(related_objects_types.into_iter()) + .zip(related_objects_types) .map(|(id, r#type)| OcelProducedObjectAfterConsume::new(id, Some(r#type))) .collect(); @@ -197,10 +198,10 @@ impl<'a> OcelDataExtractor<'a> { } fn parse_object_id(event: &XesEventImpl, object_id_attr: &str) -> Option> { - if let Some(map) = event.payload_map().as_ref() { - if let Some(object_id) = map.get(object_id_attr).as_ref() { - return Some(object_id.to_string_repr()); - } + if let Some(map) = event.payload_map().as_ref() + && let Some(object_id) = map.get(object_id_attr).as_ref() + { + return Some(object_id.to_string_repr()); } None @@ -211,27 +212,27 @@ impl<'a> OcelDataExtractor<'a> { related_objects_ids_attr: Option<&String>, delimiter: &str, ) -> Option>> { - if let Some(related_objects_ids_attr) = related_objects_ids_attr { - if let Some(objects_ids) = payload.get(related_objects_ids_attr) { - let parsed_ids: Vec> = objects_ids - .to_string_repr() - .trim() - .split(delimiter) - .filter_map(|s| { - if s.len() > 0 { - Some(HeapedOrOwned::Owned(s.to_string())) - } else { - None - } - }) - .collect(); - - if parsed_ids.len() == 0 { - return None; - } - - return Some(parsed_ids); + if let Some(related_objects_ids_attr) = related_objects_ids_attr + && let Some(objects_ids) = payload.get(related_objects_ids_attr) + { + let parsed_ids: Vec> = objects_ids + .to_string_repr() + .trim() + .split(delimiter) + .filter_map(|s| { + if !s.is_empty() { + Some(HeapedOrOwned::Owned(s.to_string())) + } else { + None + } + }) + .collect(); + + if parsed_ids.is_empty() { + return None; } + + return Some(parsed_ids); } None diff --git a/Ficus/src/rust/ficus/src/features/discovery/timeline/software_data/extractors/pie_charts.rs b/Ficus/src/rust/ficus/src/features/discovery/timeline/software_data/extractors/pie_charts.rs index b03016541..87058e108 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/timeline/software_data/extractors/pie_charts.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/timeline/software_data/extractors/pie_charts.rs @@ -3,7 +3,7 @@ use crate::{ features::discovery::timeline::software_data::{ extraction_config::{PieChartExtractionConfig, SoftwareDataExtractionConfig}, extractors::{ - core::{parse_or_err, EventGroupSoftwareDataExtractor, SoftwareDataExtractionError}, + core::{EventGroupSoftwareDataExtractor, SoftwareDataExtractionError, parse_or_err}, utils::RegexParingResult, }, models::{GenericEnhancementBase, HistogramData, HistogramEntry, SoftwareData}, diff --git a/Ficus/src/rust/ficus/src/features/discovery/timeline/software_data/extractors/simple_counter.rs b/Ficus/src/rust/ficus/src/features/discovery/timeline/software_data/extractors/simple_counter.rs index 7f2ce0c07..9f5664cc4 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/timeline/software_data/extractors/simple_counter.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/timeline/software_data/extractors/simple_counter.rs @@ -3,7 +3,7 @@ use crate::{ features::discovery::timeline::software_data::{ extraction_config::{SimpleCountExtractionConfig, SoftwareDataExtractionConfig}, extractors::{ - core::{parse_or_err, EventGroupSoftwareDataExtractor, SoftwareDataExtractionError}, + core::{EventGroupSoftwareDataExtractor, SoftwareDataExtractionError, parse_or_err}, utils::RegexParingResult, }, models::{GenericEnhancementBase, SimpleCounterData, SoftwareData}, @@ -60,7 +60,7 @@ impl<'a> EventGroupSoftwareDataExtractor for SimpleCounterExtractor<'a> { 1. }; - (*result.entry(config.base().name().to_string()).or_insert((config.base(), 0.))).1 += count; + result.entry(config.base().name().to_string()).or_insert((config.base(), 0.)).1 += count; } } Err(err) => return Err(err.clone()), diff --git a/Ficus/src/rust/ficus/src/features/discovery/timeline/software_data/extractors/utils.rs b/Ficus/src/rust/ficus/src/features/discovery/timeline/software_data/extractors/utils.rs index 1b4243669..2e6f390a1 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/timeline/software_data/extractors/utils.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/timeline/software_data/extractors/utils.rs @@ -23,7 +23,7 @@ impl NameCreationStrategy { result.push_str(many_attributes.separator()); } - if many_attributes.attributes().len() > 0 { + if !many_attributes.attributes().is_empty() { result.remove(result.len() - 1); } diff --git a/Ficus/src/rust/ficus/src/features/discovery/timeline/utils.rs b/Ficus/src/rust/ficus/src/features/discovery/timeline/utils.rs index 110d44cbe..06ee13044 100644 --- a/Ficus/src/rust/ficus/src/features/discovery/timeline/utils.rs +++ b/Ficus/src/rust/ficus/src/features/discovery/timeline/utils.rs @@ -8,39 +8,27 @@ use crate::{ use chrono::{DateTime, Utc}; pub fn extract_thread_id(event: &TEvent, thread_attribute: &str) -> Option { - if let Some(map) = event.payload_map() { - if let Some(value) = map.get(thread_attribute) { - Some(value.to_string_repr().as_str().to_owned()) - } else { - None - } - } else { - None - } + let value = event.payload_map()?.get(thread_attribute)?; + Some(value.to_string_repr().as_str().to_owned()) } pub fn get_stamp(event: &XesEventImpl, attribute: Option<&String>) -> Result { - if let Some(attribute) = attribute { - if let Some(map) = event.payload_map() { - if let Some(value) = map.get(attribute) { - match value { - EventPayloadValue::Int32(v) => return Ok(*v as i64), - EventPayloadValue::Int64(v) => return Ok(*v), - EventPayloadValue::Uint32(v) => return Ok(*v as i64), - EventPayloadValue::Date(date) => return get_utc_date_stamp(date), - _ => {} - }; - } - } + if let Some(attribute) = attribute + && let Some(map) = event.payload_map() + && let Some(value) = map.get(attribute) + { + match value { + EventPayloadValue::Int32(v) => return Ok(*v as i64), + EventPayloadValue::Int64(v) => return Ok(*v), + EventPayloadValue::Uint32(v) => return Ok(*v as i64), + EventPayloadValue::Date(date) => return get_utc_date_stamp(date), + _ => {} + }; } get_utc_date_stamp(event.timestamp()) } fn get_utc_date_stamp(date: &DateTime) -> Result { - if let Some(utc_stamp) = date.timestamp_nanos_opt() { - Ok(utc_stamp) - } else { - Err(LogThreadsDiagramError::NotSupportedEventStamp) - } + date.timestamp_nanos_opt().ok_or(LogThreadsDiagramError::NotSupportedEventStamp) } diff --git a/Ficus/src/rust/ficus/src/features/mutations/mutations.rs b/Ficus/src/rust/ficus/src/features/mutations/mutations.rs index 42ad20e0c..926aa9909 100644 --- a/Ficus/src/rust/ficus/src/features/mutations/mutations.rs +++ b/Ficus/src/rust/ficus/src/features/mutations/mutations.rs @@ -13,8 +13,13 @@ where }) } -pub const ARTIFICIAL_START_EVENT_NAME: &'static str = "ARTIFICIAL_START"; -pub const ARTIFICIAL_END_EVENT_NAME: &'static str = "ARTIFICIAL_END"; +pub const ARTIFICIAL_START_EVENT_NAME: &str = "ARTIFICIAL_START"; +pub const ARTIFICIAL_END_EVENT_NAME: &str = "ARTIFICIAL_END"; + +enum StartOrEnd { + Start, + End, +} pub fn add_artificial_start_end_activities( log: &mut TLog, @@ -26,49 +31,56 @@ pub fn add_artificial_start_end_activities( let mut trace = trace.borrow_mut(); let events = trace.events_mut(); - if add_start_events { - let name = ARTIFICIAL_START_EVENT_NAME.to_string(); + let mut add_artificial_event = |start_or_end: StartOrEnd| { + let name = match start_or_end { + StartOrEnd::Start => ARTIFICIAL_START_EVENT_NAME, + StartOrEnd::End => ARTIFICIAL_END_EVENT_NAME, + } + .to_string(); + let artificial_start_event = if events.is_empty() { - TLog::TEvent::new_with_min_date(name) + match start_or_end { + StartOrEnd::Start => TLog::TEvent::new_with_min_date(name), + StartOrEnd::End => TLog::TEvent::new_with_max_date(name), + } } else { - let first_event = events.first().expect("!events.is_empty()"); + let reference_event = match start_or_end { + StartOrEnd::Start => events.first(), + StartOrEnd::End => events.last(), + } + .expect("!events.is_empty()"); - let mut start_event = TLog::TEvent::new(name, first_event.borrow().timestamp().clone()); - copy_payload::(&first_event.borrow(), &mut start_event, attributes_to_copy); + let mut start_event = TLog::TEvent::new(name, *reference_event.borrow().timestamp()); + copy_payload::(&reference_event.borrow(), &mut start_event, attributes_to_copy); start_event }; - events.insert(0, Rc::new(RefCell::new(artificial_start_event))); - } - - if add_end_events { - let name = ARTIFICIAL_END_EVENT_NAME.to_string(); - let artificial_end_event = if events.is_empty() { - TLog::TEvent::new_with_max_date(name) - } else { - let last_event = events.last().expect("!events.is_empty()"); + let insertion_index = match start_or_end { + StartOrEnd::Start => 0, + StartOrEnd::End => events.len(), + }; - let mut end_event = TLog::TEvent::new(name, last_event.borrow().timestamp().clone()); - copy_payload::(&last_event.borrow(), &mut end_event, attributes_to_copy); + events.insert(insertion_index, Rc::new(RefCell::new(artificial_start_event))); + }; - end_event - }; + if add_start_events { + add_artificial_event(StartOrEnd::Start); + } - events.push(Rc::new(RefCell::new(artificial_end_event))); + if add_end_events { + add_artificial_event(StartOrEnd::End); } } } fn copy_payload(from: &TLog::TEvent, to: &mut TLog::TEvent, attributes_to_copy: Option<&Vec>) { - if let Some(attributes_to_copy) = attributes_to_copy { - if let Some(payload_map) = from.payload_map() { - for attr in attributes_to_copy { - if let Some(value) = payload_map.get(attr) { - to.add_or_update_payload(attr.clone(), value.clone()); - } - } - } + let Some(attributes_to_copy) = attributes_to_copy else { return }; + let Some(payload_map) = from.payload_map() else { return }; + + for attr in attributes_to_copy { + let Some(value) = payload_map.get(attr) else { continue }; + to.add_or_update_payload(attr.clone(), value.clone()); } } @@ -80,10 +92,7 @@ pub fn append_attributes_to_name(log: &mut TLog, attributes: &Ve for attribute in attributes { let value = match payload { None => None, - Some(payload) => match payload.get(attribute) { - None => None, - Some(value) => Some(value.to_string_repr()), - }, + Some(payload) => payload.get(attribute).map(|value| value.to_string_repr()), }; let attribute_value_string = match value { diff --git a/Ficus/src/rust/ficus/src/features/mutations/split.rs b/Ficus/src/rust/ficus/src/features/mutations/split.rs index 2646d22b2..67bf2e4e2 100644 --- a/Ficus/src/rust/ficus/src/features/mutations/split.rs +++ b/Ficus/src/rust/ficus/src/features/mutations/split.rs @@ -1,12 +1,14 @@ +use crate::event_log::core::{event::event::Event, event_log::EventLog, trace::trace::Trace}; use std::{ cell::RefCell, - collections::{hash_map::DefaultHasher, HashMap}, + collections::{ + HashMap, + hash_map::{DefaultHasher, Entry}, + }, hash::{Hash, Hasher}, rc::Rc, }; -use crate::event_log::core::{event::event::Event, event_log::EventLog, trace::trace::Trace}; - struct TracePointer { pub trace: Rc>, pub index: usize, @@ -72,10 +74,10 @@ where for index in 0..traces.len() { let trace = Rc::clone(&traces[index]); let len = trace.borrow().events().len(); - if len_to_traces.contains_key(&len) { - (*len_to_traces.get_mut(&len).unwrap()).push(TracePointer::new(trace, index)); + if let Entry::Vacant(e) = len_to_traces.entry(len) { + e.insert(vec![TracePointer::new(trace, index)]); } else { - len_to_traces.insert(len, vec![TracePointer::new(trace, index)]); + (*len_to_traces.get_mut(&len).unwrap()).push(TracePointer::new(trace, index)); } } @@ -144,10 +146,10 @@ where event.name().hash(&mut hasher); let hash_code = hasher.finish(); - if hashes_to_traces.contains_key(&hash_code) { - (*hashes_to_traces.get_mut(&hash_code).unwrap()).push((*trace).clone()); + if let Entry::Vacant(e) = hashes_to_traces.entry(hash_code) { + e.insert(vec![(*trace).clone()]); } else { - hashes_to_traces.insert(hash_code, vec![(*trace).clone()]); + (*hashes_to_traces.get_mut(&hash_code).unwrap()).push((*trace).clone()); } } diff --git a/Ficus/src/rust/ficus/src/features/streaming/counters/lossy_count.rs b/Ficus/src/rust/ficus/src/features/streaming/counters/lossy_count.rs index a032f5f4c..6d56c8fb9 100644 --- a/Ficus/src/rust/ficus/src/features/streaming/counters/lossy_count.rs +++ b/Ficus/src/rust/ficus/src/features/streaming/counters/lossy_count.rs @@ -49,7 +49,7 @@ where self.state.insert(element, LossyCountState::new(value, (bucket_number - 1) as f64)); } - if self.observed_items_count % self.batch_size == 0 { + if self.observed_items_count.is_multiple_of(self.batch_size) { self.prune(bucket_number as f64); } } diff --git a/Ficus/src/rust/ficus/src/features/streaming/counters/sliding_window.rs b/Ficus/src/rust/ficus/src/features/streaming/counters/sliding_window.rs index 8011dfaae..48002eeba 100644 --- a/Ficus/src/rust/ficus/src/features/streaming/counters/sliding_window.rs +++ b/Ficus/src/rust/ficus/src/features/streaming/counters/sliding_window.rs @@ -46,10 +46,10 @@ impl StreamingCounter for } fn get(&self, key: &TKey) -> Option> { - match self.storage.get(key) { - None => None, - Some(entry) => Some(entry.to_streaming_counter_entry(key.clone(), entry.count as f64 / self.counts_sum() as f64)), - } + self + .storage + .get(key) + .map(|entry| entry.to_streaming_counter_entry(key.clone(), entry.count as f64 / self.counts_sum() as f64)) } fn above_threshold(&self, threshold: f64) -> Vec> { @@ -95,7 +95,7 @@ impl SlidingWindow { } fn counts_sum(&self) -> u64 { - self.storage.iter().map(|(_, v)| v.count).sum() + self.storage.values().map(|v| v.count).sum() } pub fn add(&mut self, key: TKey, value: ValueUpdateKind, stamp: DateTime) { diff --git a/Ficus/src/rust/ficus/src/features/streaming/mod.rs b/Ficus/src/rust/ficus/src/features/streaming/mod.rs index 25b17c6ea..fa18356eb 100644 --- a/Ficus/src/rust/ficus/src/features/streaming/mod.rs +++ b/Ficus/src/rust/ficus/src/features/streaming/mod.rs @@ -1 +1,2 @@ pub mod counters; +pub mod t1; diff --git a/Ficus/src/rust/ficus/src/features/streaming/t1/configs.rs b/Ficus/src/rust/ficus/src/features/streaming/t1/configs.rs new file mode 100644 index 000000000..0fb013d00 --- /dev/null +++ b/Ficus/src/rust/ficus/src/features/streaming/t1/configs.rs @@ -0,0 +1,44 @@ +#[derive(Clone)] +pub struct EventsTimeoutConfiguration { + timeout_ms: u64, +} + +impl EventsTimeoutConfiguration { + pub fn new(timeout_ms: u64) -> Self { + Self { timeout_ms } + } + + pub fn timeout_ms(&self) -> u64 { + self.timeout_ms + } +} + +#[derive(Clone)] +pub struct TracesTimeoutConfiguration { + timeout_ms: u64, +} + +impl TracesTimeoutConfiguration { + pub fn new(timeout_ms: u64) -> Self { + Self { timeout_ms } + } + + pub fn timeout_ms(&self) -> u64 { + self.timeout_ms + } +} + +#[derive(Clone)] +pub struct TracesQueueConfiguration { + queue_capacity: u64, +} + +impl TracesQueueConfiguration { + pub fn new(queue_capacity: u64) -> Self { + Self { queue_capacity } + } + + pub fn queue_capacity(&self) -> u64 { + self.queue_capacity + } +} diff --git a/Ficus/src/rust/ficus/src/grpc/kafka/streaming/t1/filterers.rs b/Ficus/src/rust/ficus/src/features/streaming/t1/filterers.rs similarity index 95% rename from Ficus/src/rust/ficus/src/grpc/kafka/streaming/t1/filterers.rs rename to Ficus/src/rust/ficus/src/features/streaming/t1/filterers.rs index 7302c5803..95de20107 100644 --- a/Ficus/src/rust/ficus/src/grpc/kafka/streaming/t1/filterers.rs +++ b/Ficus/src/rust/ficus/src/features/streaming/t1/filterers.rs @@ -3,7 +3,7 @@ use crate::{ core::{event::event::Event, event_log::EventLog, trace::trace::Trace}, xes::xes_event_log::XesEventLogImpl, }, - grpc::kafka::streaming::t1::configs::{EventsTimeoutConfiguration, TracesQueueConfiguration, TracesTimeoutConfiguration}, + features::streaming::t1::configs::{EventsTimeoutConfiguration, TracesQueueConfiguration, TracesTimeoutConfiguration}, }; use chrono::Utc; use log::debug; diff --git a/Ficus/src/rust/ficus/src/features/streaming/t1/mod.rs b/Ficus/src/rust/ficus/src/features/streaming/t1/mod.rs new file mode 100644 index 000000000..eebbd9147 --- /dev/null +++ b/Ficus/src/rust/ficus/src/features/streaming/t1/mod.rs @@ -0,0 +1,2 @@ +pub mod configs; +pub mod filterers; diff --git a/Ficus/src/rust/ficus/src/grpc/kafka/streaming/t1/configs.rs b/Ficus/src/rust/ficus/src/grpc/kafka/streaming/t1/configs.rs deleted file mode 100644 index 3eefe6f06..000000000 --- a/Ficus/src/rust/ficus/src/grpc/kafka/streaming/t1/configs.rs +++ /dev/null @@ -1,85 +0,0 @@ -use crate::{ - ficus_proto::{grpc_t1_streaming_configuration::Configuration, GrpcT1StreamingConfiguration}, - grpc::kafka::streaming::t1::{ - filterers::{EventsTimeoutFiltererImpl, T1LogFilterer, TracesQueueFiltererImpl, TracesTimeoutFiltererImpl}, - processors::T1StreamingProcessor, - }, -}; - -pub enum T1StreamingConfiguration { - EventsTimeout(EventsTimeoutConfiguration), - TracesTimeout(TracesTimeoutConfiguration), - TracesQueue(TracesQueueConfiguration), -} - -impl T1StreamingConfiguration { - pub fn new(grpc_config: &GrpcT1StreamingConfiguration) -> Option { - match grpc_config.configuration.as_ref() { - None => None, - Some(c) => Some(match c { - Configuration::EventsTimeout(et) => { - T1StreamingConfiguration::EventsTimeout(EventsTimeoutConfiguration::new(et.events_timeout_ms as u64)) - } - Configuration::TracesTimeout(tt) => { - T1StreamingConfiguration::TracesTimeout(TracesTimeoutConfiguration::new(tt.traces_timeout_ms as u64)) - } - Configuration::TracesQueueConfiguration(tq) => { - T1StreamingConfiguration::TracesQueue(TracesQueueConfiguration::new(tq.queue_capacity as u64)) - } - }), - } - } - - pub fn create_processor(&self) -> T1StreamingProcessor { - T1StreamingProcessor::new(match self { - T1StreamingConfiguration::EventsTimeout(c) => T1LogFilterer::EventsTimeoutFilterer(EventsTimeoutFiltererImpl::new(c.clone())), - T1StreamingConfiguration::TracesTimeout(c) => T1LogFilterer::TracesTimeoutFilterer(TracesTimeoutFiltererImpl::new(c.clone())), - T1StreamingConfiguration::TracesQueue(c) => T1LogFilterer::TracesQueueFilterer(TracesQueueFiltererImpl::new(c.clone())), - }) - } -} - -#[derive(Clone)] -pub struct EventsTimeoutConfiguration { - timeout_ms: u64, -} - -impl EventsTimeoutConfiguration { - pub fn new(timeout_ms: u64) -> Self { - Self { timeout_ms } - } - - pub fn timeout_ms(&self) -> u64 { - self.timeout_ms.clone() - } -} - -#[derive(Clone)] -pub struct TracesTimeoutConfiguration { - timeout_ms: u64, -} - -impl TracesTimeoutConfiguration { - pub fn new(timeout_ms: u64) -> Self { - Self { timeout_ms } - } - - pub fn timeout_ms(&self) -> u64 { - self.timeout_ms.clone() - } -} - -#[derive(Clone)] -pub struct TracesQueueConfiguration { - queue_capacity: u64, -} - -impl TracesQueueConfiguration { - pub fn new(queue_capacity: u64) -> Self { - Self { queue_capacity } - } - - pub fn queue_capacity(&self) -> u64 { - self.queue_capacity.clone() - } -} diff --git a/Ficus/src/rust/ficus/src/lib.rs b/Ficus/src/rust/ficus/src/lib.rs index 74bb82bcc..0696d9398 100644 --- a/Ficus/src/rust/ficus/src/lib.rs +++ b/Ficus/src/rust/ficus/src/lib.rs @@ -1,9 +1,4 @@ pub mod event_log; pub mod features; -pub mod grpc; pub mod pipelines; pub mod utils; - -pub mod ficus_proto { - tonic::include_proto!("ficus"); -} diff --git a/Ficus/src/rust/ficus/src/pipelines/activities_parts.rs b/Ficus/src/rust/ficus/src/pipelines/activities_parts.rs index 9e0253d17..fde1104c1 100644 --- a/Ficus/src/rust/ficus/src/pipelines/activities_parts.rs +++ b/Ficus/src/rust/ficus/src/pipelines/activities_parts.rs @@ -15,23 +15,24 @@ use crate::{ patterns::{ activity_instances, activity_instances::{ + ActivitiesLogSource, ActivityInTraceInfo, AdjustingMode, SubTraceKind, UNDEF_ACTIVITY_NAME, UndefActivityHandlingStrategy, add_unattached_activities, count_underlying_events, create_activity_name, create_log_from_unattached_events, create_new_log_from_activities_instances, extract_activities_instances, extract_activities_instances_strict, - substitute_underlying_events, ActivitiesLogSource, ActivityInTraceInfo, AdjustingMode, SubTraceKind, UndefActivityHandlingStrategy, - UNDEF_ACTIVITY_NAME, + substitute_underlying_events, }, - pattern_info::{UnderlyingPatternKind, UNDERLYING_PATTERN_KIND_KEY}, + pattern_info::{UNDERLYING_PATTERN_KIND_KEY, UnderlyingPatternKind}, repeat_sets::{build_repeat_set_tree_from_repeats, build_repeat_sets}, }, }, + pipeline_part, pipelines::{ context::PipelineInfrastructure, keys::context_keys::{ ACTIVITIES_KEY, ACTIVITIES_LOGS_SOURCE_KEY, ACTIVITY_IN_TRACE_FILTER_KIND_KEY, ACTIVITY_LEVEL_KEY, ACTIVITY_NAME_KEY, - ADJUSTING_MODE_KEY, DISCOVER_ACTIVITY_INSTANCES_STRICT_KEY, EVENTS_COUNT_KEY, EVENT_CLASS_REGEX_KEY, EVENT_LOG_KEY, + ADJUSTING_MODE_KEY, DISCOVER_ACTIVITY_INSTANCES_STRICT_KEY, EVENT_CLASS_REGEX_KEY, EVENT_LOG_KEY, EVENTS_COUNT_KEY, EXECUTE_ONLY_ON_LAST_EXTRACTION_KEY, HASHES_EVENT_LOG_KEY, LOG_SERIALIZATION_FORMAT_KEY, MIN_ACTIVITY_LENGTH_KEY, - NARROW_ACTIVITIES_KEY, PATH_KEY, PATTERNS_DISCOVERY_STRATEGY_KEY, PATTERNS_KEY, PATTERNS_KIND_KEY, PIPELINE_KEY, REGEXES_KEY, - REGEX_KEY, REPEAT_SETS_KEY, TRACE_ACTIVITIES_KEY, UNDEF_ACTIVITY_HANDLING_STRATEGY_KEY, UNDERLYING_EVENTS_COUNT_KEY, + NARROW_ACTIVITIES_KEY, PATH_KEY, PATTERNS_DISCOVERY_STRATEGY_KEY, PATTERNS_KEY, PATTERNS_KIND_KEY, PIPELINE_KEY, REGEX_KEY, + REGEXES_KEY, REPEAT_SETS_KEY, TRACE_ACTIVITIES_KEY, UNDEF_ACTIVITY_HANDLING_STRATEGY_KEY, UNDERLYING_EVENTS_COUNT_KEY, }, pipeline_parts::PipelineParts, }, @@ -80,12 +81,10 @@ impl FromStr for ActivitiesLogsSourceDto { } impl PipelineParts { - pub(super) fn discover_activities() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_ACTIVITIES, &|context, _, config| { - let activity_level = Self::get_user_data(config, &ACTIVITY_LEVEL_KEY)?; - Self::do_discover_activities(context, *activity_level, config) - }) - } + pipeline_part!(discover_activities, |context: &mut PipelineContext, _, config: &UserDataImpl| { + let activity_level = Self::get_user_data(config, &ACTIVITY_LEVEL_KEY)?; + Self::do_discover_activities(context, *activity_level, config) + }); pub(super) fn do_discover_activities( context: &mut PipelineContext, @@ -95,20 +94,17 @@ impl PipelineParts { let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; let patterns = Self::get_user_data(context, &PATTERNS_KEY)?; let hashed_log = Self::get_user_data(context, &HASHES_EVENT_LOG_KEY)?; - let event_class_regex = match Self::get_user_data(config, &EVENT_CLASS_REGEX_KEY) { - Ok(regex) => Some(regex), - Err(_) => None, - }; + let event_class_regex = Self::get_user_data(config, &EVENT_CLASS_REGEX_KEY).ok(); - let repeat_sets = build_repeat_sets(&hashed_log, patterns); + let repeat_sets = build_repeat_sets(hashed_log, patterns); let underlying_patterns_kind = Self::get_user_data(context, &UNDERLYING_PATTERN_KIND_KEY).unwrap_or(&UnderlyingPatternKind::Unknown); let tree = build_repeat_set_tree_from_repeats( - &hashed_log, + hashed_log, &repeat_sets, activity_level as usize, - underlying_patterns_kind.clone(), + *underlying_patterns_kind, |sub_array| create_activity_name(log, sub_array, event_class_regex), ); @@ -116,18 +112,19 @@ impl PipelineParts { Ok(()) } - pub(super) fn discover_activities_instances() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_ACTIVITIES_INSTANCES, &|context, _, config| { + pipeline_part!( + discover_activities_instances, + |context: &mut PipelineContext, _, config: &UserDataImpl| { Self::do_discover_activities_instances(context, config)?; Ok(()) - }) - } + } + ); pub(super) fn do_discover_activities_instances( context: &mut PipelineContext, config: &UserDataImpl, ) -> Result<(), PipelinePartExecutionError> { - let mut tree = Self::get_user_data_mut(context, &ACTIVITIES_KEY)?; + let tree = Self::get_user_data_mut(context, &ACTIVITIES_KEY)?; let narrow = Self::get_user_data(config, &NARROW_ACTIVITIES_KEY)?; let hashed_log = Self::get_user_data(context, &HASHES_EVENT_LOG_KEY)?; let min_events_in_activity = *Self::get_user_data(config, &MIN_ACTIVITY_LENGTH_KEY)?; @@ -135,26 +132,18 @@ impl PipelineParts { let discover_activities_instances_strict = Self::get_user_data(config, &DISCOVER_ACTIVITY_INSTANCES_STRICT_KEY)?; let instances = match discover_activities_instances_strict { - true => extract_activities_instances_strict(&hashed_log, &tree), - false => extract_activities_instances( - &hashed_log, - &mut tree, - narrow, - min_events_in_activity as usize, - activity_filter_kind, - ), + true => extract_activities_instances_strict(hashed_log, tree), + false => extract_activities_instances(hashed_log, tree, narrow, min_events_in_activity as usize, activity_filter_kind), }; context.put_concrete(TRACE_ACTIVITIES_KEY.key(), instances); Ok(()) } - pub(super) fn create_log_from_activities() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::CREATE_LOG_FROM_ACTIVITIES, &|context, _, config| { - Self::do_create_log_from_activities(context, config)?; - Ok(()) - }) - } + pipeline_part!(create_log_from_activities, &|context, _, config| { + Self::do_create_log_from_activities(context, config)?; + Ok(()) + }); pub(super) fn do_create_log_from_activities( context: &mut PipelineContext, @@ -174,10 +163,10 @@ impl PipelineParts { let log = create_new_log_from_activities_instances(log, instances, &strategy, &|info, events| { let stamp = if events.len() == 1 { - events.first().unwrap().borrow().timestamp().clone() + *events.first().unwrap().borrow().timestamp() } else { - let first_stamp = events.first().unwrap().borrow().timestamp().clone(); - let delta: TimeDelta = events.iter().skip(1).map(|e| e.borrow().timestamp().clone() - first_stamp).sum(); + let first_stamp = *events.first().unwrap().borrow().timestamp(); + let delta: TimeDelta = events.iter().skip(1).map(|e| *e.borrow().timestamp() - first_stamp).sum(); first_stamp + delta / (events.len() as i32 - 1) }; @@ -192,8 +181,9 @@ impl PipelineParts { Ok(()) } - pub(super) fn discover_activities_instances_for_several_levels() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_ACTIVITIES_FOR_SEVERAL_LEVEL, &|context, infra, config| { + pipeline_part!( + discover_activities_for_several_levels, + |context: &mut PipelineContext, infra: &PipelineInfrastructure, config: &UserDataImpl| { let event_classes = Self::get_user_data(config, ®EXES_KEY)?; let initial_activity_level = *Self::get_user_data(config, &ACTIVITY_LEVEL_KEY)?; let patterns_kind = Self::get_user_data(config, &PATTERNS_KIND_KEY)?; @@ -204,13 +194,13 @@ impl PipelineParts { let min_events_in_activity = Self::get_user_data(config, &MIN_ACTIVITY_LENGTH_KEY)?; let activity_filter_kind = Self::get_user_data(config, &ACTIVITY_IN_TRACE_FILTER_KIND_KEY)?; - let mut index = 0; - for event_class_regex in event_classes.into_iter().rev() { - let mut config = UserDataImpl::new(); + for (index, event_class_regex) in event_classes.iter().rev().enumerate() { + let mut config: UserDataImpl = Default::default(); + config.put_concrete(PATTERNS_KIND_KEY.key(), *patterns_kind); config.put_concrete(EVENT_CLASS_REGEX_KEY.key(), event_class_regex.to_owned()); config.put_concrete(ADJUSTING_MODE_KEY.key(), *adjusting_mode); - config.put_concrete(ACTIVITY_LEVEL_KEY.key(), initial_activity_level + index); + config.put_concrete(ACTIVITY_LEVEL_KEY.key(), initial_activity_level + index as u32); config.put_concrete(PATTERNS_DISCOVERY_STRATEGY_KEY.key(), *patterns_discovery_strategy); config.put_concrete(NARROW_ACTIVITIES_KEY.key(), *narrow_activities); config.put_concrete(EVENTS_COUNT_KEY.key(), *events_count); @@ -218,13 +208,11 @@ impl PipelineParts { config.put_concrete(ACTIVITY_IN_TRACE_FILTER_KIND_KEY.key(), *activity_filter_kind); Self::adjust_with_activities_from_unattached_events(context, infra, &config)?; - - index += 1; } Ok(()) - }) - } + } + ); pub(super) fn adjust_with_activities_from_unattached_events( old_context: &mut PipelineContext, @@ -238,12 +226,11 @@ impl PipelineParts { let adjusting_mode = *Self::get_user_data(config, &ADJUSTING_MODE_KEY)?; let log = Self::get_user_data(old_context, &EVENT_LOG_KEY)?; - let mut new_context = PipelineContext::empty_from(&old_context); + let mut new_context = PipelineContext::empty_from(old_context); if adjusting_mode == AdjustingMode::FromUnattachedSubTraces { - match Self::get_user_data(old_context, &TRACE_ACTIVITIES_KEY) { - Ok(activities) => new_context.put_concrete(EVENT_LOG_KEY.key(), create_log_from_unattached_events(log, activities)), - Err(_) => {} + if let Ok(activities) = Self::get_user_data(old_context, &TRACE_ACTIVITIES_KEY) { + new_context.put_concrete(EVENT_LOG_KEY.key(), create_log_from_unattached_events(log, activities)) } } else { new_context.put_concrete(EVENT_LOG_KEY.key(), log.clone()); @@ -266,8 +253,9 @@ impl PipelineParts { Ok(()) } - pub(super) fn discover_activities_in_unattached_subtraces() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_ACTIVITIES_IN_UNATTACHED_SUBTRACES, &|context, _, config| { + pipeline_part!( + discover_activities_in_unattached_subtraces, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; let mut existing_activities = &Self::create_empty_activities(log); @@ -296,8 +284,8 @@ impl PipelineParts { context.put_concrete(TRACE_ACTIVITIES_KEY.key(), new_activities); Ok(()) - }) - } + } + ); pub(super) fn create_add_unattached_events_part(&self, config: UserDataImpl) -> DefaultPipelinePart { let name = Self::DISCOVER_ACTIVITIES_IN_UNATTACHED_SUBTRACES; @@ -315,12 +303,10 @@ impl PipelineParts { activities } - pub(super) fn clear_activities_related_stuff() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::CLEAR_ACTIVITIES, &|context, _, _| { - Self::do_clear_activities_related_stuff(context); - Ok(()) - }) - } + pipeline_part!(clear_activities, |context: &mut PipelineContext, _, _| { + Self::do_clear_activities_related_stuff(context); + Ok(()) + }); pub(super) fn do_clear_activities_related_stuff(context: &mut PipelineContext) { context.remove_concrete(ACTIVITIES_KEY.key()); @@ -329,21 +315,21 @@ impl PipelineParts { context.remove_concrete(REPEAT_SETS_KEY.key()); } - pub(super) fn get_number_of_underlying_events() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::GET_UNDERLYING_EVENTS_COUNT, &|context, infra, _| { - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - let count = count_underlying_events(log); - infra.log(format!("Number of underlying events: {}", &count).as_str())?; + pipeline_part!(get_underlying_events_count, |context: &mut PipelineContext, + infra: &PipelineInfrastructure, + _| { + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + let count = count_underlying_events(log); + infra.log(format!("Number of underlying events: {}", &count).as_str())?; - context.put_concrete(UNDERLYING_EVENTS_COUNT_KEY.key(), count); - Ok(()) - }) - } + context.put_concrete(UNDERLYING_EVENTS_COUNT_KEY.key(), count); + Ok(()) + }); pub(super) fn execute_with_activities_instances( activities: &Vec, trace_len: usize, - handler: &mut impl FnMut(SubTraceKind) -> (), + handler: &mut impl FnMut(SubTraceKind), ) -> Result<(), PipelinePartExecutionError> { let mut index = 0usize; for activity in activities { @@ -351,7 +337,7 @@ impl PipelineParts { handler(SubTraceKind::Unattached(index, activity.start_pos() - index)); } - handler(SubTraceKind::Attached(&activity)); + handler(SubTraceKind::Attached(activity)); index = *activity.start_pos() + *activity.length(); } @@ -362,8 +348,9 @@ impl PipelineParts { Ok(()) } - pub(super) fn discover_activities_until_no_more() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_ACTIVITIES_UNTIL_NO_MORE, &|context, infra, config| { + pipeline_part!( + discover_activities_until_no_more, + |context: &mut PipelineContext, infra: &PipelineInfrastructure, config: &UserDataImpl| { let activity_level = *Self::get_user_data(config, &ACTIVITY_LEVEL_KEY)?; let after_activities_extraction_pipeline = Self::get_user_data(config, &PIPELINE_KEY); let execute_only_after_last_extraction = *Self::get_user_data(config, &EXECUTE_ONLY_ON_LAST_EXTRACTION_KEY)?; @@ -413,25 +400,26 @@ impl PipelineParts { return Ok(()); } } - }) - } + } + ); - pub(super) fn execute_with_each_activity_log() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::EXECUTE_WITH_EACH_ACTIVITY_LOG, &|context, infra, config| { + pipeline_part!( + execute_with_each_activity_log, + |context: &mut PipelineContext, infra: &PipelineInfrastructure, config: &UserDataImpl| { let pipeline = Self::get_user_data(config, &PIPELINE_KEY)?; let activities_to_logs = Self::create_activities_to_logs(context, config)?; for (activity_name, activity_log) in activities_to_logs { let mut temp_context = context.clone(); - temp_context.put_concrete(&EVENT_LOG_KEY.key(), activity_log.borrow().clone()); - temp_context.put_concrete(&ACTIVITY_NAME_KEY.key(), activity_name.clone()); + temp_context.put_concrete(EVENT_LOG_KEY.key(), activity_log.borrow().clone()); + temp_context.put_concrete(ACTIVITY_NAME_KEY.key(), activity_name.clone()); pipeline.execute(&mut temp_context, infra)?; } Ok(()) - }) - } + } + ); fn create_activities_to_logs( context: &mut PipelineContext, @@ -452,75 +440,72 @@ impl PipelineParts { } } - pub(super) fn substitute_underlying_events() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::SUBSTITUTE_UNDERLYING_EVENTS, &|context, _, _| { - let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; - let mut new_log = XesEventLogImpl::empty(); - - for trace in log.traces() { - let mut new_trace = XesTraceImpl::empty(); - for event in trace.borrow().events() { - substitute_underlying_events(event, &mut new_trace); - } + pipeline_part!(substitute_underlying_events, |context: &mut PipelineContext, _, _| { + let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; + let mut new_log = XesEventLogImpl::empty(); - new_log.push(Rc::new(RefCell::new(new_trace))); + for trace in log.traces() { + let mut new_trace = XesTraceImpl::empty(); + for event in trace.borrow().events() { + substitute_underlying_events(event, &mut new_trace); } - context.put_concrete(EVENT_LOG_KEY.key(), new_log); - Ok(()) - }) - } + new_log.push(Rc::new(RefCell::new(new_trace))); + } - pub(super) fn apply_class_extractor() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::APPLY_CLASS_EXTRACTOR, &|context, _, config| { - let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; + context.put_concrete(EVENT_LOG_KEY.key(), new_log); + Ok(()) + }); - let event_class_regex = Self::get_user_data(config, &EVENT_CLASS_REGEX_KEY)?; - let event_class_regex = Self::try_parse_regex(event_class_regex)?; + pipeline_part!(apply_class_extractor, |context: &mut PipelineContext, _, config: &UserDataImpl| { + let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; - let filter_regex = Self::get_user_data(config, ®EX_KEY)?; - let filter_regex = Self::try_parse_regex(filter_regex)?; + let event_class_regex = Self::get_user_data(config, &EVENT_CLASS_REGEX_KEY)?; + let event_class_regex = Self::try_parse_regex(event_class_regex)?; - for trace in log.traces() { - for event in trace.borrow().events() { - if !filter_regex.is_match(event.borrow().name()).ok().unwrap() { - continue; - } + let filter_regex = Self::get_user_data(config, ®EX_KEY)?; + let filter_regex = Self::try_parse_regex(filter_regex)?; - let borrowed_event = event.borrow(); - let found_match = event_class_regex.find(borrowed_event.name()); - if found_match.is_err() { - continue; - } + for trace in log.traces() { + for event in trace.borrow().events() { + if !filter_regex.is_match(event.borrow().name()).ok().unwrap() { + continue; + } - let (start, end) = if let Ok(Some(found_match)) = found_match { - (found_match.start(), found_match.end()) - } else { - (0, borrowed_event.name().len()) - }; + let borrowed_event = event.borrow(); + let found_match = event_class_regex.find(borrowed_event.name()); + if found_match.is_err() { + continue; + } - drop(found_match); - drop(borrowed_event); + let (start, end) = if let Ok(Some(found_match)) = found_match { + (found_match.start(), found_match.end()) + } else { + (0, borrowed_event.name().len()) + }; - if start == 0 { - let new_name = event.borrow().name()[start..end].to_owned(); - event.borrow_mut().set_name(new_name); - } + drop(found_match); + drop(borrowed_event); + + if start == 0 { + let new_name = event.borrow().name()[start..end].to_owned(); + event.borrow_mut().set_name(new_name); } } + } - Ok(()) - }) - } + Ok(()) + }); - pub(super) fn serialize_activities_logs() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::SERIALIZE_ACTIVITIES_LOGS, &|context, _, config| { + pipeline_part!( + serialize_activities_logs, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let logs_to_activities = Self::create_activities_to_logs(context, config)?; let path = Path::new(Self::get_user_data(config, &PATH_KEY)?); let format = Self::get_user_data(config, &LOG_SERIALIZATION_FORMAT_KEY)?; let mut log_number = 1; - for (_, log) in &logs_to_activities { + for log in logs_to_activities.values() { let save_path = path.join(format!("log_{}.{}", log_number, format.extension())); let save_path = save_path.as_os_str().to_str().unwrap(); @@ -539,11 +524,12 @@ impl PipelineParts { } Ok(()) - }) - } + } + ); - pub(super) fn reverse_hierarchy_indices() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::REVERSE_HIERARCHY_INDICES, &|context, _, _| { + pipeline_part!( + reverse_hierarchy_indices, + |context: &mut PipelineContext, _, _config: &UserDataImpl| { let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; const HIERARCHY_LEVEL: &str = "hierarchy_level_"; @@ -553,8 +539,7 @@ impl PipelineParts { for event in trace.events() { let event = event.borrow(); for (key, _) in event.ordered_payload() { - if key.starts_with(HIERARCHY_LEVEL) { - let level = &key[HIERARCHY_LEVEL.len()..]; + if let Some(level) = key.strip_prefix(HIERARCHY_LEVEL) { let level = level.parse::().ok().unwrap(); max_level = max_level.max(level); } @@ -568,7 +553,7 @@ impl PipelineParts { let mut updates = vec![]; let mut event = event.borrow_mut(); if let Some(payload) = event.payload_map() { - let keys = payload.keys().into_iter().filter(|k| k.starts_with(HIERARCHY_LEVEL)); + let keys = payload.keys().filter(|k| k.starts_with(HIERARCHY_LEVEL)); for key in keys { let level = &key[HIERARCHY_LEVEL.len()..].parse::().ok().unwrap(); let new_level = max_level - level; @@ -591,6 +576,6 @@ impl PipelineParts { } Ok(()) - }) - } + } + ); } diff --git a/Ficus/src/rust/ficus/src/pipelines/annotations_parts.rs b/Ficus/src/rust/ficus/src/pipelines/annotations_parts.rs index 479948d4e..be217a2b7 100644 --- a/Ficus/src/rust/ficus/src/pipelines/annotations_parts.rs +++ b/Ficus/src/rust/ficus/src/pipelines/annotations_parts.rs @@ -9,6 +9,7 @@ use crate::{ petri_net::DefaultPetriNet, }, }, + pipeline_part, pipelines::{ context::PipelineContext, errors::pipeline_errors::{PipelinePartExecutionError, RawPartExecutionError}, @@ -27,16 +28,12 @@ use crate::{ }; impl PipelineParts { - pub(super) fn annotate_petri_net_count() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::ANNOTATE_PETRI_NET_COUNT, &|context, _, config| { - Self::annotate_petri_net( - &PETRI_NET_COUNT_ANNOTATION_KEY, - context, - config, - |log, net, terminate_on_unreplayable_traces| annotate_with_counts(log, net, terminate_on_unreplayable_traces), - ) - }) - } + pipeline_part!( + annotate_petri_net_count, + |context: &mut PipelineContext, _, config: &UserDataImpl| { + Self::annotate_petri_net(&PETRI_NET_COUNT_ANNOTATION_KEY, context, config, annotate_with_counts) + } + ); fn annotate_petri_net( annotation_key: &DefaultContextKey>, @@ -58,30 +55,28 @@ impl PipelineParts { } } - pub(super) fn annotate_petri_net_frequency() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::ANNOTATE_PETRI_NET_FREQUENCY, &|context, _, config| { - Self::annotate_petri_net( - &PETRI_NET_FREQUENCY_ANNOTATION_KEY, - context, - config, - |log, net, terminate_on_unreplayable_traces| annotate_with_frequencies(log, net, terminate_on_unreplayable_traces), - ) - }) - } + pipeline_part!( + annotate_petri_net_frequency, + |context: &mut PipelineContext, _, config: &UserDataImpl| { + Self::annotate_petri_net(&PETRI_NET_FREQUENCY_ANNOTATION_KEY, context, config, annotate_with_frequencies) + } + ); - pub(super) fn annotate_petri_net_trace_frequency() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::ANNOTATE_PETRI_NET_TRACE_FREQUENCY, &|context, _, config| { + pipeline_part!( + annotate_petri_net_trace_frequency, + |context: &mut PipelineContext, _, config: &UserDataImpl| { Self::annotate_petri_net( &PETRI_NET_TRACE_FREQUENCY_ANNOTATION_KEY, context, config, - |log, net, terminate_on_unreplayable_traces| annotate_with_trace_frequency(log, net, terminate_on_unreplayable_traces), + annotate_with_trace_frequency, ) - }) - } + } + ); - pub(super) fn annotate_graph_with_time_performance() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::ANNOTATE_GRAPH_WITH_TIME, &|context, _, config| { + pipeline_part!( + annotate_graph_with_time, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; let graph = Self::get_user_data(context, &GRAPH_KEY)?; let annotation_kind = *Self::get_user_data(config, &TIME_ANNOTATION_KIND_KEY)?; @@ -96,23 +91,21 @@ impl PipelineParts { Ok(()) } } - }) - } + } + ); - pub(super) fn create_ocel_annotation_for_dag() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::CREATE_OCEL_ANNOTATION_FOR_DAG, &|context, _, _| { - let graph = Self::get_user_data(context, &GRAPH_KEY)?; + pipeline_part!(create_ocel_annotation_for_dag, |context: &mut PipelineContext, _, _| { + let graph = Self::get_user_data(context, &GRAPH_KEY)?; - match create_ocel_annotation_for_dag(graph) { - Ok(annotation) => { - context.put_concrete(OCEL_ANNOTATION_KEY.key(), annotation); - Ok(()) - } - Err(err) => { - let message = format!("Failed to create ocel annotation, error: {}", err.to_string()); - Err(PipelinePartExecutionError::new_raw(message)) - } + match create_ocel_annotation_for_dag(graph) { + Ok(annotation) => { + context.put_concrete(OCEL_ANNOTATION_KEY.key(), annotation); + Ok(()) } - }) - } + Err(err) => { + let message = format!("Failed to create ocel annotation, error: {}", err); + Err(PipelinePartExecutionError::new_raw(message)) + } + } + }); } diff --git a/Ficus/src/rust/ficus/src/pipelines/cases.rs b/Ficus/src/rust/ficus/src/pipelines/cases.rs index 4e5bc1961..8dac1a2c5 100644 --- a/Ficus/src/rust/ficus/src/pipelines/cases.rs +++ b/Ficus/src/rust/ficus/src/pipelines/cases.rs @@ -1,30 +1,32 @@ use crate::{ features::cases::cases_discovery::discover_cases, + pipeline_part, pipelines::{ + context::{PipelineContext, PipelineInfrastructure}, keys::context_keys::{END_CASE_REGEX_KEY, EVENT_LOG_KEY, INLINE_INNER_CASES_KEY, PIPELINE_KEY, START_CASE_REGEX_KEY}, pipeline_parts::PipelineParts, pipelines::{PipelinePart, PipelinePartFactory}, }, - utils::user_data::user_data::UserData, + utils::user_data::user_data::{UserData, UserDataImpl}, }; impl PipelineParts { - pub(super) fn discover_cases() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_CASES, &|context, infra, config| { - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - let pipeline = Self::get_user_data(config, &PIPELINE_KEY)?; - let start_case_regex = Self::get_user_data(config, &START_CASE_REGEX_KEY)?; - let end_case_regex = Self::get_user_data(config, &END_CASE_REGEX_KEY)?; - let inline_inner_cases = *Self::get_user_data(config, &INLINE_INNER_CASES_KEY)?; + pipeline_part!(discover_cases, |context: &mut PipelineContext, + infra: &PipelineInfrastructure, + config: &UserDataImpl| { + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + let pipeline = Self::get_user_data(config, &PIPELINE_KEY)?; + let start_case_regex = Self::get_user_data(config, &START_CASE_REGEX_KEY)?; + let end_case_regex = Self::get_user_data(config, &END_CASE_REGEX_KEY)?; + let inline_inner_cases = *Self::get_user_data(config, &INLINE_INNER_CASES_KEY)?; - let new_log = discover_cases(log, start_case_regex.as_str(), end_case_regex.as_str(), inline_inner_cases); + let new_log = discover_cases(log, start_case_regex.as_str(), end_case_regex.as_str(), inline_inner_cases); - let mut new_context = context.clone(); - new_context.put_concrete(EVENT_LOG_KEY.key(), new_log); + let mut new_context = context.clone(); + new_context.put_concrete(EVENT_LOG_KEY.key(), new_log); - pipeline.execute(&mut new_context, infra)?; + pipeline.execute(&mut new_context, infra)?; - Ok(()) - }) - } + Ok(()) + }); } diff --git a/Ficus/src/rust/ficus/src/pipelines/clustering.rs b/Ficus/src/rust/ficus/src/pipelines/clustering.rs index 4e2bd20b0..a3860d4bb 100644 --- a/Ficus/src/rust/ficus/src/pipelines/clustering.rs +++ b/Ficus/src/rust/ficus/src/pipelines/clustering.rs @@ -7,13 +7,14 @@ use crate::{ dbscan::clusterize_activities_dbscan, k_means::{clusterize_activities_k_means, clusterize_activities_k_means_grid_search}, }, - common::{transform_to_ficus_dataset, CommonVisualizationParams}, + common::{CommonVisualizationParams, transform_to_ficus_dataset}, traces::{ dbscan::{clusterize_log_by_traces_dbscan, clusterize_log_by_traces_dbscan_grid_search}, k_means::clusterize_log_by_traces_kmeans_grid_search, traces_params::{FeatureCountKind, TracesClusteringParams}, }, }, + pipeline_part, pipelines::{ context::{PipelineContext, PipelineInfrastructure}, errors::pipeline_errors::{PipelinePartExecutionError, RawPartExecutionError}, @@ -21,8 +22,8 @@ use crate::{ ACTIVITIES_REPR_SOURCE_KEY, ACTIVITY_LEVEL_KEY, CLUSTERS_COUNT_KEY, COLORS_HOLDER_KEY, DISTANCE_KEY, EVENT_CLASS_REGEX_KEY, EVENT_LOG_KEY, FEATURE_COUNT_KIND_KEY, LABELED_LOG_TRACES_DATASET_KEY, LABELED_TRACES_ACTIVITIES_DATASET_KEY, LEARNING_ITERATIONS_COUNT_KEY, MIN_EVENTS_IN_CLUSTERS_COUNT_KEY, MIN_POINTS_IN_CLUSTER_ARRAY_KEY, PERCENT_FROM_MAX_VALUE_KEY, - PIPELINE_KEY, PUT_NOISE_EVENTS_IN_ONE_CLUSTER_KEY, TOLERANCES_KEY, TOLERANCE_KEY, TRACES_ACTIVITIES_DATASET_KEY, - TRACES_REPR_SOURCE_KEY, TRACE_ACTIVITIES_KEY, + PIPELINE_KEY, PUT_NOISE_EVENTS_IN_ONE_CLUSTER_KEY, TOLERANCE_KEY, TOLERANCES_KEY, TRACE_ACTIVITIES_KEY, + TRACES_ACTIVITIES_DATASET_KEY, TRACES_REPR_SOURCE_KEY, }, multithreading::FeatureCountKindDto, pipeline_parts::PipelineParts, @@ -32,8 +33,9 @@ use crate::{ }; impl PipelineParts { - pub(super) fn clusterize_activities_from_traces_k_means() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::CLUSTERIZE_ACTIVITIES_FROM_TRACES_KMEANS, &|context, _, config| { + pipeline_part!( + clusterize_activities_from_traces_kmeans, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let mut params = Self::create_activities_clustering_params(context, config)?; let clusters_count = *Self::get_user_data(config, &CLUSTERS_COUNT_KEY)? as usize; let learning_iterations_count = *Self::get_user_data(config, &LEARNING_ITERATIONS_COUNT_KEY)? as usize; @@ -45,8 +47,8 @@ impl PipelineParts { context.put_concrete(LABELED_TRACES_ACTIVITIES_DATASET_KEY.key(), labeled_dataset); Ok(()) - }) - } + } + ); fn create_common_vis_params<'a>( context: &'a PipelineContext, @@ -99,8 +101,9 @@ impl PipelineParts { } } - pub(super) fn clusterize_activities_from_traces_k_means_grid_search() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::CLUSTERIZE_ACTIVITIES_FROM_TRACES_KMEANS_GRID_SEARCH, &|context, _, config| { + pipeline_part!( + clusterize_activities_from_traces_kmeans_grid_search, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let learning_iterations_count = *Self::get_user_data(config, &LEARNING_ITERATIONS_COUNT_KEY)? as usize; let mut params = Self::create_activities_clustering_params(context, config)?; @@ -111,11 +114,12 @@ impl PipelineParts { context.put_concrete(LABELED_TRACES_ACTIVITIES_DATASET_KEY.key(), labeled_dataset); Ok(()) - }) - } + } + ); - pub(super) fn clusterize_activities_from_traces_dbscan() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::CLUSTERIZE_ACTIVITIES_FROM_TRACES_DBSCAN, &|context, _, config| { + pipeline_part!( + clusterize_activities_from_traces_dbscan, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let min_points_in_cluster = *Self::get_user_data(config, &MIN_EVENTS_IN_CLUSTERS_COUNT_KEY)? as usize; let put_noise_events_in_one_cluster = *Self::get_user_data(config, &PUT_NOISE_EVENTS_IN_ONE_CLUSTER_KEY)?; let mut params = Self::create_activities_clustering_params(context, config)?; @@ -127,11 +131,12 @@ impl PipelineParts { context.put_concrete(LABELED_TRACES_ACTIVITIES_DATASET_KEY.key(), labeled_dataset); Ok(()) - }) - } + } + ); - pub fn clusterize_log_by_traces_k_means_grid_search() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::CLUSTERIZE_LOG_TRACES_K_MEANS_GRID_SEARCH, &|context, infra, config| { + pipeline_part!( + clusterize_log_traces_k_means_grid_search, + |context: &mut PipelineContext, infra: &PipelineInfrastructure, config: &UserDataImpl| { let mut params = Self::create_traces_clustering_params(context, config)?; let learning_iterations_count = *Self::get_user_data(config, &LEARNING_ITERATIONS_COUNT_KEY)? as u64; let tolerance = *Self::get_user_data(config, &TOLERANCE_KEY)?; @@ -141,7 +146,7 @@ impl PipelineParts { Err(error) => return Err(error.into()), }; - if let Some(after_clusterization_pipeline) = Self::get_user_data(config, &PIPELINE_KEY).ok() { + if let Ok(after_clusterization_pipeline) = Self::get_user_data(config, &PIPELINE_KEY) { for log in logs { let mut new_context = context.clone(); new_context.put_concrete(EVENT_LOG_KEY.key(), log); @@ -153,11 +158,12 @@ impl PipelineParts { context.put_concrete(LABELED_LOG_TRACES_DATASET_KEY.key(), labeled_dataset); Ok(()) - }) - } + } + ); - pub(super) fn create_traces_activities_dataset() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::CREATE_TRACES_ACTIVITIES_DATASET, &|context, _, config| { + pipeline_part!( + create_traces_activities_dataset, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let params = Self::create_activities_visualization_params(context, config)?; let (dataset, processed, classes) = match create_dataset(¶ms) { @@ -170,8 +176,8 @@ impl PipelineParts { context.put_concrete(TRACES_ACTIVITIES_DATASET_KEY.key(), ficus_dataset); Ok(()) - }) - } + } + ); pub(crate) fn create_traces_clustering_params<'a>( context: &'a mut PipelineContext, @@ -198,8 +204,9 @@ impl PipelineParts { }) } - pub(super) fn clusterize_log_traces() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::CLUSTERIZE_LOG_TRACES, &|context, infra, config| { + pipeline_part!( + clusterize_log_traces, + |context: &mut PipelineContext, infra: &PipelineInfrastructure, config: &UserDataImpl| { let mut params = Self::create_traces_clustering_params(context, config)?; let after_clusterization_pipeline = Self::get_user_data(config, &PIPELINE_KEY)?; let min_points_in_cluster = *Self::get_user_data(config, &MIN_EVENTS_IN_CLUSTERS_COUNT_KEY)? as usize; @@ -216,11 +223,12 @@ impl PipelineParts { Self::execute_with_temp_event_logs(context, infra, new_logs.0, after_clusterization_pipeline)?; Ok(()) - }) - } + } + ); - pub(super) fn clusterize_log_traces_dbscan_grid_search() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::CLUSTERIZE_LOG_TRACES_DBSCAN_GRID_SEARCH, &|context, infra, config| { + pipeline_part!( + clusterize_log_traces_dbscan_grid_search, + |context: &mut PipelineContext, infra: &PipelineInfrastructure, config: &UserDataImpl| { let mut params = Self::create_traces_clustering_params(context, config)?; let after_clusterization_pipeline = Self::get_user_data(config, &PIPELINE_KEY)?; @@ -241,8 +249,8 @@ impl PipelineParts { Self::execute_with_temp_event_logs(context, infra, new_logs.0, after_clusterization_pipeline)?; Ok(()) - }) - } + } + ); fn execute_with_temp_event_logs( context: &mut PipelineContext, diff --git a/Ficus/src/rust/ficus/src/pipelines/context.rs b/Ficus/src/rust/ficus/src/pipelines/context.rs index 07723a33c..f1707c4de 100644 --- a/Ficus/src/rust/ficus/src/pipelines/context.rs +++ b/Ficus/src/rust/ficus/src/pipelines/context.rs @@ -50,22 +50,22 @@ pub struct PipelineContext<'a> { impl<'a> PipelineContext<'a> { pub fn new_with_logging(parts: &'a PipelineParts) -> Self { Self { - user_data: UserDataImpl::new(), + user_data: Default::default(), pipeline_parts: Some(parts), } } pub fn empty() -> Self { Self { - user_data: UserDataImpl::new(), + user_data: Default::default(), pipeline_parts: None, } } pub fn empty_from(other: &'a PipelineContext) -> Self { Self { - user_data: UserDataImpl::new(), - pipeline_parts: other.pipeline_parts.clone(), + user_data: Default::default(), + pipeline_parts: other.pipeline_parts, } } } diff --git a/Ficus/src/rust/ficus/src/pipelines/discovery_parts.rs b/Ficus/src/rust/ficus/src/pipelines/discovery_parts.rs index 2bc95f10d..0aa663481 100644 --- a/Ficus/src/rust/ficus/src/pipelines/discovery_parts.rs +++ b/Ficus/src/rust/ficus/src/pipelines/discovery_parts.rs @@ -10,13 +10,14 @@ use crate::{ alpha_plus_plus_nfc::alpha_plus_plus_nfc::discover_petri_net_alpha_plus_plus_nfc, providers::{alpha_plus_provider::AlphaPlusRelationsProviderImpl, alpha_provider::DefaultAlphaRelationsProvider}, }, + ecfg::discovery_xes::discover_ecfg_from_event_log, fuzzy::fuzzy_miner::discover_graph_fuzzy, heuristic::heuristic_miner::discover_petri_net_heuristic, petri_net::{marking::ensure_initial_marking, pnml_serialization::serialize_to_pnml_file}, relations::triangle_relation::OfflineTriangleRelation, - root_sequence::discovery_xes::discover_root_sequence_graph_from_event_log, }, }, + pipeline_part, pipelines::{ context::PipelineContext, errors::pipeline_errors::{PipelinePartExecutionError, RawPartExecutionError}, @@ -30,53 +31,45 @@ use crate::{ pipeline_parts::PipelineParts, pipelines::PipelinePartFactory, }, - utils::user_data::user_data::UserData, + utils::user_data::user_data::{UserData, UserDataImpl}, }; impl PipelineParts { - pub(super) fn discover_petri_net_alpha() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_PETRI_NET_ALPHA, &|context, _, _| { - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - let event_log_info = OfflineEventLogInfo::create_from(EventLogInfoCreationDto::default(log)); - let provider = DefaultAlphaRelationsProvider::new(&event_log_info); - let discovered_net = discover_petri_net_alpha(&provider); + pipeline_part!(discover_petri_net_alpha, |context: &mut PipelineContext, _, _| { + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + let event_log_info = OfflineEventLogInfo::create_from(EventLogInfoCreationDto::default(log)); + let provider = DefaultAlphaRelationsProvider::new(&event_log_info); + let discovered_net = discover_petri_net_alpha(&provider); - context.put_concrete(PETRI_NET_KEY.key(), discovered_net); + context.put_concrete(PETRI_NET_KEY.key(), discovered_net); - Ok(()) - }) - } + Ok(()) + }); - pub(super) fn discover_petri_net_alpha_stream() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_PETRI_NET_ALPHA_STREAM, &|context, _, _| { - let event_log_info = Self::get_user_data(context, &EVENT_LOG_INFO_KEY)?; - let provider = DefaultAlphaRelationsProvider::new(event_log_info); - let discovered_net = discover_petri_net_alpha(&provider); + pipeline_part!(discover_petri_net_alpha_stream, |context: &mut PipelineContext, _, _| { + let event_log_info = Self::get_user_data(context, &EVENT_LOG_INFO_KEY)?; + let provider = DefaultAlphaRelationsProvider::new(event_log_info); + let discovered_net = discover_petri_net_alpha(&provider); - context.put_concrete(PETRI_NET_KEY.key(), discovered_net); + context.put_concrete(PETRI_NET_KEY.key(), discovered_net); - Ok(()) - }) - } + Ok(()) + }); - pub(super) fn serialize_petri_net() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::SERIALIZE_PETRI_NET, &|context, _, config| { - let petri_net = Self::get_user_data(context, &PETRI_NET_KEY)?; - let save_path = Self::get_user_data(config, &PATH_KEY)?; - let use_names_as_ids = *Self::get_user_data(config, &PNML_USE_NAMES_AS_IDS_KEY)?; + pipeline_part!(serialize_petri_net, |context: &mut PipelineContext, _, config: &UserDataImpl| { + let petri_net = Self::get_user_data(context, &PETRI_NET_KEY)?; + let save_path = Self::get_user_data(config, &PATH_KEY)?; + let use_names_as_ids = *Self::get_user_data(config, &PNML_USE_NAMES_AS_IDS_KEY)?; - match serialize_to_pnml_file(petri_net, save_path, use_names_as_ids) { - Ok(_) => Ok(()), - Err(error) => Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(error.to_string()))), - } - }) - } + match serialize_to_pnml_file(petri_net, save_path, use_names_as_ids) { + Ok(_) => Ok(()), + Err(error) => Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(error.to_string()))), + } + }); - pub(super) fn discover_petri_net_alpha_plus() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_PETRI_NET_ALPHA_PLUS, &|context, _, _| { - Self::do_discover_petri_net_alpha_plus(context, false) - }) - } + pipeline_part!(discover_petri_net_alpha_plus, |context: &mut PipelineContext, _, _| { + Self::do_discover_petri_net_alpha_plus(context, false) + }); fn do_discover_petri_net_alpha_plus(context: &mut PipelineContext, alpha_plus_plus: bool) -> Result<(), PipelinePartExecutionError> { let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; @@ -98,47 +91,40 @@ impl PipelineParts { Ok(()) } - pub(super) fn discover_petri_net_alpha_plus_plus() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_PETRI_NET_ALPHA_PLUS_PLUS, &|context, _, _| { - Self::do_discover_petri_net_alpha_plus(context, true) - }) - } + pipeline_part!(discover_petri_net_alpha_plus_plus, |context: &mut PipelineContext, _, _| { + Self::do_discover_petri_net_alpha_plus(context, true) + }); - pub(super) fn discover_petri_net_alpha_plus_plus_nfc() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_PETRI_NET_ALPHA_PLUS_PLUS_NFC, &|context, _, _| { - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - let discovered_petri_net = discover_petri_net_alpha_plus_plus_nfc(log); - context.put_concrete(PETRI_NET_KEY.key(), discovered_petri_net); + pipeline_part!(discover_petri_net_alpha_plus_plus_nfc, |context: &mut PipelineContext, _, _| { + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + let discovered_petri_net = discover_petri_net_alpha_plus_plus_nfc(log); + context.put_concrete(PETRI_NET_KEY.key(), discovered_petri_net); - Ok(()) - }) - } + Ok(()) + }); - pub(super) fn discover_directly_follows_graph() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_DFG, &|context, _, config| { - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - let creation_dto = match Self::get_user_data(config, &THREAD_ATTRIBUTE_KEY) { - Ok(thread_attribute) => EventLogInfoCreationDto::default_thread(log, thread_attribute.to_owned()), - Err(_) => EventLogInfoCreationDto::default(log), - }; + pipeline_part!(discover_dfg, |context: &mut PipelineContext, _, config: &UserDataImpl| { + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + let creation_dto = match Self::get_user_data(config, &THREAD_ATTRIBUTE_KEY) { + Ok(thread_attribute) => EventLogInfoCreationDto::default_thread(log, thread_attribute.to_owned()), + Err(_) => EventLogInfoCreationDto::default(log), + }; - context.put_concrete(GRAPH_KEY.key(), construct_dfg(&OfflineEventLogInfo::create_from(creation_dto))); + context.put_concrete(GRAPH_KEY.key(), construct_dfg(&OfflineEventLogInfo::create_from(creation_dto))); - Ok(()) - }) - } + Ok(()) + }); - pub(super) fn discover_directly_follows_graph_stream() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_DFG_STREAM, &|context, _, _| { - let info = Self::get_user_data(context, &EVENT_LOG_INFO_KEY)?; - context.put_concrete(GRAPH_KEY.key(), construct_dfg(info)); + pipeline_part!(discover_dfg_stream, |context: &mut PipelineContext, _, _| { + let info = Self::get_user_data(context, &EVENT_LOG_INFO_KEY)?; + context.put_concrete(GRAPH_KEY.key(), construct_dfg(info)); - Ok(()) - }) - } + Ok(()) + }); - pub(super) fn discover_directly_follows_graph_by_attribute() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_DFG_BY_ATTRIBUTE, &|context, _, config| { + pipeline_part!( + discover_dfg_by_attribute, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; let attribute = Self::get_user_data(config, &ATTRIBUTE_KEY)?; let dfg = construct_dfg_by_attribute(log, attribute); @@ -146,11 +132,12 @@ impl PipelineParts { context.put_concrete(GRAPH_KEY.key(), dfg); Ok(()) - }) - } + } + ); - pub(super) fn discover_petri_net_heuristic_miner() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_PETRI_NET_HEURISTIC, &|context, _, config| { + pipeline_part!( + discover_petri_net_heuristic, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; let dependency_threshold = *Self::get_user_data(config, &DEPENDENCY_THRESHOLD_KEY)?; let positive_observations_threshold = *Self::get_user_data(config, &POSITIVE_OBSERVATIONS_THRESHOLD_KEY)? as usize; @@ -174,60 +161,54 @@ impl PipelineParts { context.put_concrete(PETRI_NET_KEY.key(), petri_net); Ok(()) - }) - } + } + ); - pub(super) fn discover_fuzzy_graph() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_FUZZY_GRAPH, &|context, _, config| { - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - let unary_freq_threshold = *Self::get_user_data(config, &UNARY_FREQUENCY_THRESHOLD_KEY)?; - let binary_sig_threshold = *Self::get_user_data(config, &BINARY_FREQUENCY_SIGNIFICANCE_THRESHOLD_KEY)?; - let preserve_ratio = *Self::get_user_data(config, &PRESERVE_THRESHOLD_KEY)?; - let ratio_threshold = *Self::get_user_data(config, &RATIO_THRESHOLD_KEY)?; - let utility_rate = *Self::get_user_data(config, &UTILITY_RATE_KEY)?; - let edge_cutoff_threshold = *Self::get_user_data(config, &EDGE_CUTOFF_THRESHOLD_KEY)?; - let node_cutoff_threshold = *Self::get_user_data(config, &NODE_CUTOFF_THRESHOLD_KEY)?; - - let graph = discover_graph_fuzzy( - log, - unary_freq_threshold, - binary_sig_threshold, - preserve_ratio, - ratio_threshold, - utility_rate, - edge_cutoff_threshold, - node_cutoff_threshold, - ); + pipeline_part!(discover_fuzzy_graph, |context: &mut PipelineContext, _, config: &UserDataImpl| { + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + let unary_freq_threshold = *Self::get_user_data(config, &UNARY_FREQUENCY_THRESHOLD_KEY)?; + let binary_sig_threshold = *Self::get_user_data(config, &BINARY_FREQUENCY_SIGNIFICANCE_THRESHOLD_KEY)?; + let preserve_ratio = *Self::get_user_data(config, &PRESERVE_THRESHOLD_KEY)?; + let ratio_threshold = *Self::get_user_data(config, &RATIO_THRESHOLD_KEY)?; + let utility_rate = *Self::get_user_data(config, &UTILITY_RATE_KEY)?; + let edge_cutoff_threshold = *Self::get_user_data(config, &EDGE_CUTOFF_THRESHOLD_KEY)?; + let node_cutoff_threshold = *Self::get_user_data(config, &NODE_CUTOFF_THRESHOLD_KEY)?; + + let graph = discover_graph_fuzzy( + log, + unary_freq_threshold, + binary_sig_threshold, + preserve_ratio, + ratio_threshold, + utility_rate, + edge_cutoff_threshold, + node_cutoff_threshold, + ); + + context.put_concrete(GRAPH_KEY.key(), graph.to_default_graph()); - context.put_concrete(GRAPH_KEY.key(), graph.to_default_graph()); + Ok(()) + }); - Ok(()) - }) - } + pipeline_part!(ensure_initial_marking, |context: &mut PipelineContext, _, _| { + let petri_net = Self::get_user_data_mut(context, &PETRI_NET_KEY)?; + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + ensure_initial_marking(log, petri_net); - pub(super) fn ensure_initial_marking() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::ENSURE_INITIAL_MARKING, &|context, _, _| { - let petri_net = Self::get_user_data_mut(context, &PETRI_NET_KEY)?; - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - ensure_initial_marking(log, petri_net); + Ok(()) + }); - Ok(()) - }) - } + pipeline_part!(discover_ecfg, |context: &mut PipelineContext, _, config: &UserDataImpl| { + let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; + let root_sequence_kind = Self::get_user_data(config, &ROOT_SEQUENCE_KIND_KEY)?; + let merge_sequences_of_events = Self::get_user_data(config, &MERGE_SEQUENCES_OF_EVENTS_KEY)?; - pub(super) fn discover_root_sequence_graph() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_ROOT_SEQUENCE_GRAPH, &|context, _, config| { - let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; - let root_sequence_kind = Self::get_user_data(config, &ROOT_SEQUENCE_KIND_KEY)?; - let merge_sequences_of_events = Self::get_user_data(config, &MERGE_SEQUENCES_OF_EVENTS_KEY)?; - - match discover_root_sequence_graph_from_event_log(log, *root_sequence_kind, *merge_sequences_of_events) { - Ok(graph) => { - context.put_concrete(GRAPH_KEY.key(), graph); - Ok(()) - } - Err(err) => Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(err.to_string()))), + match discover_ecfg_from_event_log(log, *root_sequence_kind, *merge_sequences_of_events) { + Ok(graph) => { + context.put_concrete(GRAPH_KEY.key(), graph); + Ok(()) } - }) - } + Err(err) => Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(err.to_string()))), + } + }); } diff --git a/Ficus/src/rust/ficus/src/pipelines/drawing_parts.rs b/Ficus/src/rust/ficus/src/pipelines/drawing_parts.rs index 79ebda24c..b873e6d9b 100644 --- a/Ficus/src/rust/ficus/src/pipelines/drawing_parts.rs +++ b/Ficus/src/rust/ficus/src/pipelines/drawing_parts.rs @@ -8,6 +8,7 @@ use crate::{ xes::{xes_event::XesEventImpl, xes_event_log::XesEventLogImpl}, }, features::analysis::patterns::activity_instances::{SubTraceKind, UNDEF_ACTIVITY_NAME}, + pipeline_part, pipelines::{ keys::context_keys::{ ATTRIBUTE_KEY, COLORS_EVENT_LOG_KEY, COLORS_HOLDER_KEY, EVENT_LOG_KEY, EVENT_NAME_KEY, REGEX_KEY, TRACE_ACTIVITIES_KEY, @@ -17,22 +18,20 @@ use crate::{ utils::{ colors::{Color, ColoredRectangle, ColorsEventLog, ColorsHolder}, references::HeapedOrOwned, - user_data::user_data::UserData, + user_data::user_data::{UserData, UserDataImpl}, }, }; impl PipelineParts { - pub(super) fn traces_diversity_diagram() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::TRACES_DIVERSITY_DIAGRAM, &|context, _, _| { - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - let colors_holder = context.concrete_mut(COLORS_HOLDER_KEY.key()).expect("Should be initialized"); - let colors_log = Self::create_traces_diversity_colors_log(log, colors_holder, |e| HeapedOrOwned::Heaped(e.name_pointer().clone())); + pipeline_part!(traces_diversity_diagram, |context: &mut PipelineContext, _, _| { + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + let colors_holder = context.concrete_mut(COLORS_HOLDER_KEY.key()).expect("Should be initialized"); + let colors_log = Self::create_traces_diversity_colors_log(log, colors_holder, |e| HeapedOrOwned::Heaped(e.name_pointer().clone())); - context.put_concrete(COLORS_EVENT_LOG_KEY.key(), colors_log); + context.put_concrete(COLORS_EVENT_LOG_KEY.key(), colors_log); - Ok(()) - }) - } + Ok(()) + }); fn create_traces_diversity_colors_log( log: &XesEventLogImpl, @@ -43,8 +42,8 @@ impl PipelineParts { let mut traces = vec![]; for trace in log.traces() { let mut vec = vec![]; - let mut index = 0usize; - for event in trace.borrow().events() { + + for (index, event) in trace.borrow().events().iter().enumerate() { let event = event.borrow(); let colors_key = color_key_selector(&event); @@ -57,7 +56,6 @@ impl PipelineParts { let name = HeapedOrOwned::Owned(colors_key.to_owned()); vec.push(ColoredRectangle::square(name, index as f64)); - index += 1; } traces.push(vec); @@ -66,12 +64,13 @@ impl PipelineParts { ColorsEventLog { mapping, traces } } - pub(super) fn draw_placements_of_event_by_name() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DRAW_PLACEMENT_OF_EVENT_BY_NAME, &|context, _, config| { + pipeline_part!( + draw_placement_of_event_by_name, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let event_name = Self::get_user_data(config, &EVENT_NAME_KEY)?; Self::draw_events_placement(context, &|event| event.name() == event_name) - }) - } + } + ); pub(super) fn draw_events_placement( context: &mut PipelineContext, @@ -86,8 +85,8 @@ impl PipelineParts { for trace in log.traces() { let mut colors_trace = vec![]; - let mut index = 0usize; - for event in trace.borrow().events() { + + for (index, event) in trace.borrow().events().iter().enumerate() { let event = event.borrow(); let name = event.name(); if selector(&event) { @@ -102,8 +101,6 @@ impl PipelineParts { let name = HeapedOrOwned::Owned(UNDEF_ACTIVITY_NAME.to_owned()); colors_trace.push(ColoredRectangle::square(name, index as f64)); } - - index += 1; } traces.push(colors_trace); @@ -114,113 +111,111 @@ impl PipelineParts { Ok(()) } - pub(super) fn draw_events_placements_by_regex() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DRAW_PLACEMENT_OF_EVENT_BY_REGEX, &|context, _, config| { + pipeline_part!( + draw_placement_of_event_by_regex, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let regex = Self::get_user_data(config, ®EX_KEY)?; let regex = Regex::new(regex).ok().unwrap(); Self::draw_events_placement(context, &|event| regex.is_match(event.name()).ok().unwrap()) - }) - } + } + ); - pub(super) fn draw_full_activities_diagram() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DRAW_FULL_ACTIVITIES_DIAGRAM, &|context, _, _| { - let traces_activities = Self::get_user_data(context, &TRACE_ACTIVITIES_KEY)?; - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - let colors_holder = Self::get_user_data_mut(context, &COLORS_HOLDER_KEY)?; + pipeline_part!(draw_full_activities_diagram, |context: &mut PipelineContext, _, _| { + let traces_activities = Self::get_user_data(context, &TRACE_ACTIVITIES_KEY)?; + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + let colors_holder = Self::get_user_data_mut(context, &COLORS_HOLDER_KEY)?; - let mut traces = vec![]; - let mut mapping = HashMap::new(); - mapping.insert(UNDEF_ACTIVITY_NAME.to_string(), Color::black()); + let mut traces = vec![]; + let mut mapping = HashMap::new(); + mapping.insert(UNDEF_ACTIVITY_NAME.to_string(), Color::black()); - for (activities, trace) in traces_activities.into_iter().zip(log.traces().into_iter()) { - let mut colors_trace = vec![]; - let trace_length = trace.borrow().events().len(); + for (activities, trace) in traces_activities.iter().zip(log.traces().iter()) { + let mut colors_trace = vec![]; + let trace_length = trace.borrow().events().len(); + + Self::execute_with_activities_instances(activities, trace_length, &mut |sub_trace| match sub_trace { + SubTraceKind::Attached(activity) => { + let color = colors_holder.get_or_create(activity.node().borrow().name()); + let name = activity.node().borrow().name().clone(); + if !mapping.contains_key(name.as_ref().as_ref()) { + mapping.insert(name.as_ref().as_ref().to_owned(), color); + } - Self::execute_with_activities_instances(activities, trace_length, &mut |sub_trace| match sub_trace { - SubTraceKind::Attached(activity) => { - let color = colors_holder.get_or_create(activity.node().borrow().name()); - let name = activity.node().borrow().name().clone(); - if !mapping.contains_key(name.as_ref().as_ref()) { - mapping.insert(name.as_ref().as_ref().to_owned(), color); - } + let name = HeapedOrOwned::Heaped(name); + colors_trace.push(ColoredRectangle::new(name, *activity.start_pos() as f64, *activity.length() as f64)); + } + SubTraceKind::Unattached(start_pos, length) => { + colors_trace.push(ColoredRectangle::new( + HeapedOrOwned::Owned(UNDEF_ACTIVITY_NAME.to_string()), + start_pos as f64, + length as f64, + )); + } + })?; - let name = HeapedOrOwned::Heaped(name); - colors_trace.push(ColoredRectangle::new(name, *activity.start_pos() as f64, *activity.length() as f64)); - } - SubTraceKind::Unattached(start_pos, length) => { - colors_trace.push(ColoredRectangle::new( - HeapedOrOwned::Owned(UNDEF_ACTIVITY_NAME.to_string()), - start_pos as f64, - length as f64, - )); - } - })?; + traces.push(colors_trace); + } - traces.push(colors_trace); - } + context.put_concrete(COLORS_EVENT_LOG_KEY.key(), ColorsEventLog { mapping, traces }); - context.put_concrete(COLORS_EVENT_LOG_KEY.key(), ColorsEventLog { mapping, traces }); + Ok(()) + }); - Ok(()) - }) - } + pipeline_part!(draw_short_activities_diagram, |context: &mut PipelineContext, _, _| { + let traces_activities = Self::get_user_data(context, &TRACE_ACTIVITIES_KEY)?; + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + let colors_holder = Self::get_user_data_mut(context, &COLORS_HOLDER_KEY)?; - pub(super) fn draw_short_activities_diagram() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DRAW_SHORT_ACTIVITIES_DIAGRAM, &|context, _, _| { - let traces_activities = Self::get_user_data(context, &TRACE_ACTIVITIES_KEY)?; - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - let colors_holder = Self::get_user_data_mut(context, &COLORS_HOLDER_KEY)?; - - let mut traces = vec![]; - let mut mapping = HashMap::new(); - mapping.insert(UNDEF_ACTIVITY_NAME.to_owned(), Color::black()); - - for (activities, trace) in traces_activities.into_iter().zip(log.traces().into_iter()) { - let mut colors_trace = vec![]; - let mut index = 0; - let trace_length = trace.borrow().events().len(); - Self::execute_with_activities_instances(activities, trace_length, &mut |sub_trace| { - match sub_trace { - SubTraceKind::Attached(activity) => { - let color = colors_holder.get_or_create(activity.node().borrow().name()); - let name = activity.node().borrow().name().to_owned(); - - if !mapping.contains_key(activity.node().borrow().name().as_ref().as_ref()) { - mapping.insert(activity.node().borrow().name().as_ref().as_ref().to_owned(), color); - } - - let name = HeapedOrOwned::Heaped(name); - colors_trace.push(ColoredRectangle::new(name, index as f64, 1.)); - } - SubTraceKind::Unattached(_, _) => { - let ptr = HeapedOrOwned::Owned(UNDEF_ACTIVITY_NAME.to_owned()); - colors_trace.push(ColoredRectangle::new(ptr, index as f64, 1.)); + let mut traces = vec![]; + let mut mapping = HashMap::new(); + mapping.insert(UNDEF_ACTIVITY_NAME.to_owned(), Color::black()); + + for (activities, trace) in traces_activities.iter().zip(log.traces().iter()) { + let mut colors_trace = vec![]; + let mut index = 0; + let trace_length = trace.borrow().events().len(); + Self::execute_with_activities_instances(activities, trace_length, &mut |sub_trace| { + match sub_trace { + SubTraceKind::Attached(activity) => { + let color = colors_holder.get_or_create(activity.node().borrow().name()); + let name = activity.node().borrow().name().to_owned(); + + if !mapping.contains_key(activity.node().borrow().name().as_ref().as_ref()) { + mapping.insert(activity.node().borrow().name().as_ref().as_ref().to_owned(), color); } + + let name = HeapedOrOwned::Heaped(name); + colors_trace.push(ColoredRectangle::new(name, index as f64, 1.)); } + SubTraceKind::Unattached(_, _) => { + let ptr = HeapedOrOwned::Owned(UNDEF_ACTIVITY_NAME.to_owned()); + colors_trace.push(ColoredRectangle::new(ptr, index as f64, 1.)); + } + } - index += 1; - })?; + index += 1; + })?; - traces.push(colors_trace); - } + traces.push(colors_trace); + } - context.put_concrete(COLORS_EVENT_LOG_KEY.key(), ColorsEventLog { mapping, traces }); + context.put_concrete(COLORS_EVENT_LOG_KEY.key(), ColorsEventLog { mapping, traces }); - Ok(()) - }) - } + Ok(()) + }); - pub(super) fn draw_traces_diversity_diagram_by_attribute() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::TRACES_DIVERSITY_DIAGRAM_BY_ATTRIBUTE, &|context, _, config| { + pipeline_part!( + traces_diversity_diagram_by_attribute, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; let colors_holder = context.concrete_mut(COLORS_HOLDER_KEY.key()).expect("Should be initialized"); let attribute = Self::get_user_data(config, &ATTRIBUTE_KEY)?; let colors_log = Self::create_traces_diversity_colors_log(log, colors_holder, |e| { - if let Some(attributes) = e.payload_map() { - if let Some(value) = attributes.get(attribute) { - return value.to_string_repr(); - } + if let Some(attributes) = e.payload_map() + && let Some(value) = attributes.get(attribute) + { + return value.to_string_repr(); } HeapedOrOwned::Owned("UNDEF_ATTRIBUTE".to_string()) @@ -229,6 +224,6 @@ impl PipelineParts { context.put_concrete(COLORS_EVENT_LOG_KEY.key(), colors_log); Ok(()) - }) - } + } + ); } diff --git a/Ficus/src/rust/ficus/src/pipelines/filtering_parts.rs b/Ficus/src/rust/ficus/src/pipelines/filtering_parts.rs index 0700dd747..51d18d763 100644 --- a/Ficus/src/rust/ficus/src/pipelines/filtering_parts.rs +++ b/Ficus/src/rust/ficus/src/pipelines/filtering_parts.rs @@ -15,30 +15,27 @@ use crate::{ filtering::{filter_log_by_name, filter_log_by_regex, remain_events_in_event_log}, split::get_traces_groups_indices, }, + pipeline_part, pipelines::{ context::PipelineContext, - keys::context_keys::{EVENTS_COUNT_KEY, EVENT_LOG_KEY, EVENT_NAME_KEY, REGEX_KEY}, + keys::context_keys::{EVENT_LOG_KEY, EVENT_NAME_KEY, EVENTS_COUNT_KEY, REGEX_KEY}, pipeline_parts::PipelineParts, }, utils::user_data::user_data::UserDataImpl, }; impl PipelineParts { - pub(super) fn filter_log_by_event_name() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::FILTER_EVENTS_BY_NAME, &|context, _, config| { - let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; - let event_name = Self::get_user_data(config, &EVENT_NAME_KEY)?; - filter_log_by_name(log, &event_name); + pipeline_part!(filter_events_by_name, |context: &mut PipelineContext, _, config: &UserDataImpl| { + let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; + let event_name = Self::get_user_data(config, &EVENT_NAME_KEY)?; + filter_log_by_name(log, event_name); - Ok(()) - }) - } + Ok(()) + }); - pub(super) fn filter_log_by_regex() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::FILTER_EVENTS_BY_REGEX, &|context, _, config| { - Self::filter_log_by_regex_internal(context, config, |log, regex| filter_log_by_regex(log, regex)) - }) - } + pipeline_part!(filter_events_by_regex, |context: &mut PipelineContext, _, config: &UserDataImpl| { + Self::filter_log_by_regex_internal(context, config, filter_log_by_regex) + }); fn filter_log_by_regex_internal( context: &mut PipelineContext, @@ -48,7 +45,7 @@ impl PipelineParts { let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; let regex = Self::get_user_data(config, ®EX_KEY)?; - match Regex::new(®ex) { + match Regex::new(regex) { Ok(regex) => { filtering_func(log, ®ex); Ok(()) @@ -57,34 +54,31 @@ impl PipelineParts { } } - pub(super) fn remain_events_by_regex() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::REMAIN_EVENTS_BY_REGEX, &|context, _, config| { - Self::filter_log_by_regex_internal(context, config, |log, regex| remain_events_in_event_log(log, regex)) - }) - } + pipeline_part!(remain_events_by_regex, |context: &mut PipelineContext, _, config: &UserDataImpl| { + Self::filter_log_by_regex_internal(context, config, remain_events_in_event_log) + }); - pub(super) fn filter_log_by_variants() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::FILTER_LOG_BY_VARIANTS, &|context, _, _| { - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - let groups_indices: HashSet = get_traces_groups_indices(log) - .into_iter() - .map(|group| *(group.first().unwrap())) - .collect(); + pipeline_part!(filter_log_by_variants, |context: &mut PipelineContext, _, _| { + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + let groups_indices: HashSet = get_traces_groups_indices(log) + .into_iter() + .map(|group| *(group.first().unwrap())) + .collect(); - let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; - log.filter_traces(&|_, index| !groups_indices.contains(&index)); + let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; + log.filter_traces(&|_, index| !groups_indices.contains(index)); - Ok(()) - }) - } + Ok(()) + }); - pub(super) fn filter_traces_by_count() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::FILTER_TRACES_BY_EVENTS_COUNT, &|context, _, config| { + pipeline_part!( + filter_traces_by_events_count, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; let min_events_count = *Self::get_user_data(config, &EVENTS_COUNT_KEY)? as usize; log.filter_traces(&|trace, _| trace.events().len() < min_events_count); Ok(()) - }) - } + } + ); } diff --git a/Ficus/src/rust/ficus/src/pipelines/keys/context_keys.rs b/Ficus/src/rust/ficus/src/pipelines/keys/context_keys.rs index a3c2fefad..6f176df36 100644 --- a/Ficus/src/rust/ficus/src/pipelines/keys/context_keys.rs +++ b/Ficus/src/rust/ficus/src/pipelines/keys/context_keys.rs @@ -10,15 +10,15 @@ use crate::{ tandem_arrays::SubArrayInTraceInfo, }, }, + cases::CaseName, clustering::{activities::activities_params::ActivityRepresentationSource, traces::traces_params::TracesRepresentationSource}, discovery::{ + ecfg::models::RootSequenceKind, ocel::graph_annotation::OcelAnnotation, petri_net::{annotations::TimeAnnotationKind, petri_net::DefaultPetriNet}, - root_sequence::models::RootSequenceKind, timeline::{discovery::LogTimelineDiagram, software_data::extraction_config::SoftwareDataExtractionConfig}, }, }, - grpc::events::events_handler::CaseName, pipelines::{ activities_parts::{ActivitiesLogsSourceDto, UndefActivityHandlingStrategyDto}, multithreading::FeatureCountKindDto, @@ -39,112 +39,112 @@ use lazy_static::lazy_static; use std::{cell::RefCell, collections::HashMap, ops::Deref, rc::Rc}; use uuid::Uuid; -pub const CASE_NAME: &'static str = "case_name"; -pub const PROCESS_NAME: &'static str = "process_name"; -pub const SUBSCRIPTION_ID: &'static str = "subscription_id"; -pub const SUBSCRIPTION_NAME: &'static str = "subscription_name"; -pub const PIPELINE_ID: &'static str = "pipeline_id"; -pub const PIPELINE_NAME: &'static str = "pipeline_name"; -pub const UNSTRUCTURED_METADATA: &'static str = "unstructured_metadata"; -pub const PATH: &'static str = "path"; -pub const TANDEM_ARRAY_LENGTH: &'static str = "tandem_array_length"; -pub const ACTIVITY_LEVEL: &'static str = "activity_level"; -pub const NARROW_ACTIVITIES: &'static str = "narrow_activities"; -pub const EVENT_NAME: &'static str = "event_name"; -pub const REGEX: &'static str = "regex"; -pub const PATTERNS_DISCOVERY_STRATEGY: &'static str = "patterns_discovery_strategy"; -pub const OUTPUT_STRING: &'static str = "output_string"; -pub const EVENT_LOG_INFO: &'static str = "event_log_info"; -pub const UNDERLYING_EVENTS_COUNT: &'static str = "underlying_events_count"; -pub const EVENTS_COUNT: &'static str = "events_count"; -pub const REGEXES: &'static str = "regexes"; -pub const ADJUSTING_MODE: &'static str = "adjusting_mode"; -pub const EVENT_CLASS_REGEX: &'static str = "event_class_regex"; -pub const PATTERNS_KIND: &'static str = "patterns_kind"; -pub const PIPELINE: &'static str = "pipeline"; -pub const MIN_ACTIVITY_LENGTH: &'static str = "min_activity_length"; -pub const UNDEF_ACTIVITY_HANDLING_STRATEGY: &'static str = "undef_activity_handling_strategy"; -pub const ACTIVITY_IN_TRACE_FILTER_KIND: &'static str = "activity_in_trace_filter_kind"; -pub const ACTIVITIES_LOGS_SOURCE: &'static str = "activities_logs_source"; -pub const PNML_USE_NAMES_AS_IDS: &'static str = "pnml_use_names_as_ids"; -pub const DEPENDENCY_THRESHOLD: &'static str = "dependency_threshold"; -pub const POSITIVE_OBSERVATIONS_THRESHOLD: &'static str = "positive_observations_threshold"; -pub const RELATIVE_TO_BEST_THRESHOLD: &'static str = "relative_to_best_threshold"; -pub const AND_THRESHOLD: &'static str = "and_threshold"; -pub const LOOP_LENGTH_TWO_THRESHOLD: &'static str = "loop_length_two_threshold"; -pub const UNARY_FREQUENCY_THRESHOLD: &'static str = "unary_frequency_threshold"; -pub const BINARY_FREQUENCY_SIGNIFICANCE_THRESHOLD: &'static str = "binary_frequency_significance_threshold"; -pub const PRESERVE_THRESHOLD: &'static str = "preserve_threshold"; -pub const RATIO_THRESHOLD: &'static str = "ratio_threshold"; -pub const UTILITY_RATE: &'static str = "utility_rate"; -pub const EDGE_CUTOFF_THRESHOLD: &'static str = "edge_cutoff_threshold"; -pub const NODE_CUTOFF_THRESHOLD: &'static str = "node_cutoff_threshold"; -pub const TERMINATE_ON_UNREPLAYABLE_TRACES: &'static str = "terminate_on_unreplayable_traces"; -pub const CLUSTERS_COUNT: &'static str = "clusters_count"; -pub const LEARNING_ITERATIONS_COUNT: &'static str = "learning_iterations_count"; -pub const TOLERANCE: &'static str = "tolerance"; -pub const MIN_EVENTS_IN_CLUSTERS_COUNT: &'static str = "min_events_in_cluster_count"; -pub const EVENT_LOG_NAME: &'static str = "event_log_name"; -pub const BYTES: &'static str = "bytes"; +pub const CASE_NAME: &str = "case_name"; +pub const PROCESS_NAME: &str = "process_name"; +pub const SUBSCRIPTION_ID: &str = "subscription_id"; +pub const SUBSCRIPTION_NAME: &str = "subscription_name"; +pub const PIPELINE_ID: &str = "pipeline_id"; +pub const PIPELINE_NAME: &str = "pipeline_name"; +pub const UNSTRUCTURED_METADATA: &str = "unstructured_metadata"; +pub const PATH: &str = "path"; +pub const TANDEM_ARRAY_LENGTH: &str = "tandem_array_length"; +pub const ACTIVITY_LEVEL: &str = "activity_level"; +pub const NARROW_ACTIVITIES: &str = "narrow_activities"; +pub const EVENT_NAME: &str = "event_name"; +pub const REGEX: &str = "regex"; +pub const PATTERNS_DISCOVERY_STRATEGY: &str = "patterns_discovery_strategy"; +pub const OUTPUT_STRING: &str = "output_string"; +pub const EVENT_LOG_INFO: &str = "event_log_info"; +pub const UNDERLYING_EVENTS_COUNT: &str = "underlying_events_count"; +pub const EVENTS_COUNT: &str = "events_count"; +pub const REGEXES: &str = "regexes"; +pub const ADJUSTING_MODE: &str = "adjusting_mode"; +pub const EVENT_CLASS_REGEX: &str = "event_class_regex"; +pub const PATTERNS_KIND: &str = "patterns_kind"; +pub const PIPELINE: &str = "pipeline"; +pub const MIN_ACTIVITY_LENGTH: &str = "min_activity_length"; +pub const UNDEF_ACTIVITY_HANDLING_STRATEGY: &str = "undef_activity_handling_strategy"; +pub const ACTIVITY_IN_TRACE_FILTER_KIND: &str = "activity_in_trace_filter_kind"; +pub const ACTIVITIES_LOGS_SOURCE: &str = "activities_logs_source"; +pub const PNML_USE_NAMES_AS_IDS: &str = "pnml_use_names_as_ids"; +pub const DEPENDENCY_THRESHOLD: &str = "dependency_threshold"; +pub const POSITIVE_OBSERVATIONS_THRESHOLD: &str = "positive_observations_threshold"; +pub const RELATIVE_TO_BEST_THRESHOLD: &str = "relative_to_best_threshold"; +pub const AND_THRESHOLD: &str = "and_threshold"; +pub const LOOP_LENGTH_TWO_THRESHOLD: &str = "loop_length_two_threshold"; +pub const UNARY_FREQUENCY_THRESHOLD: &str = "unary_frequency_threshold"; +pub const BINARY_FREQUENCY_SIGNIFICANCE_THRESHOLD: &str = "binary_frequency_significance_threshold"; +pub const PRESERVE_THRESHOLD: &str = "preserve_threshold"; +pub const RATIO_THRESHOLD: &str = "ratio_threshold"; +pub const UTILITY_RATE: &str = "utility_rate"; +pub const EDGE_CUTOFF_THRESHOLD: &str = "edge_cutoff_threshold"; +pub const NODE_CUTOFF_THRESHOLD: &str = "node_cutoff_threshold"; +pub const TERMINATE_ON_UNREPLAYABLE_TRACES: &str = "terminate_on_unreplayable_traces"; +pub const CLUSTERS_COUNT: &str = "clusters_count"; +pub const LEARNING_ITERATIONS_COUNT: &str = "learning_iterations_count"; +pub const TOLERANCE: &str = "tolerance"; +pub const MIN_EVENTS_IN_CLUSTERS_COUNT: &str = "min_events_in_cluster_count"; +pub const EVENT_LOG_NAME: &str = "event_log_name"; +pub const BYTES: &str = "bytes"; pub const START_CASE_REGEX: &str = "start_case_regex"; pub const END_CASE_REGEX: &str = "end_case_regex"; pub const INLINE_INNER_CASES: &str = "inline_inner_cases"; -pub const EVENT_LOG: &'static str = "event_log"; -pub const ACTIVITIES: &'static str = "activities"; -pub const REPEAT_SETS: &'static str = "repeat_sets"; -pub const TRACE_ACTIVITIES: &'static str = "trace_activities"; -pub const PATTERNS: &'static str = "patterns"; -pub const PETRI_NET: &'static str = "petri_net"; -pub const ACTIVITIES_TO_LOGS: &'static str = "activities_to_logs"; -pub const ACTIVITY_NAME: &'static str = "activity_name"; -pub const HASHES_EVENT_LOG: &'static str = "hashes_event_log"; -pub const NAMES_EVENT_LOG: &'static str = "names_event_log"; -pub const COLORS_EVENT_LOG: &'static str = "colors_event_log"; -pub const COLORS_HOLDER: &'static str = "colors_holder"; -pub const GRAPH: &'static str = "graph"; -pub const GRAPHS: &'static str = "graphs"; -pub const PETRI_NET_COUNT_ANNOTATION: &'static str = "petri_net_count_annotation"; -pub const PETRI_NET_FREQUENCY_ANNOTATION: &'static str = "petri_net_frequency_annotation"; -pub const PETRI_NET_TRACE_FREQUENCY_ANNOTATION: &'static str = "petri_net_trace_frequency_annotation"; -pub const TRACES_ACTIVITIES_DATASET: &'static str = "traces_activities_dataset"; -pub const LABELED_TRACES_ACTIVITIES_DATASET: &'static str = "labeled_traces_activities_dataset"; -pub const ACTIVITIES_REPR_SOURCE: &'static str = "activities_repr_source"; -pub const DISTANCE: &'static str = "distance"; -pub const EXECUTE_ONLY_ON_LAST_EXTRACTION: &'static str = "execute_only_on_last_extraction"; -pub const LABELED_LOG_TRACES_DATASET: &'static str = "labeled_log_traces_dataset"; -pub const LOG_TRACES_DATASET: &'static str = "log_traces_dataset"; -pub const TRACES_REPR_SOURCE: &'static str = "traces_repr_source"; -pub const SYSTEM_METADATA: &'static str = "system_metadata"; -pub const LOG_SERIALIZATION_FORMAT: &'static str = "log_serialization_format"; -pub const GRAPH_TIME_ANNOTATION: &'static str = "graph_time_annotation"; -pub const ATTRIBUTE: &'static str = "attribute"; -pub const TIME_ANNOTATION_KIND: &'static str = "time_annotation_kind"; -pub const ATTRIBUTES: &'static str = "attributes"; -pub const PATHS: &'static str = "paths"; -pub const LOG_THREADS_DIAGRAM: &'static str = "log_threads_diagram"; -pub const THREAD_ATTRIBUTE: &'static str = "thread_attribute"; -pub const TIME_ATTRIBUTE: &'static str = "time_attribute"; -pub const TIME_DELTA: &'static str = "time_delta"; -pub const FEATURE_COUNT_KIND: &'static str = "feature_count_kind"; -pub const PERCENT_FROM_MAX_VALUE: &'static str = "percent_from_max_value"; -pub const TOLERANCES: &'static str = "tolerances"; -pub const MIN_POINTS_IN_CLUSTER_ARRAY: &'static str = "min_points_in_cluster_array"; -pub const EXECUTION_ID: &'static str = "execution_id"; -pub const ROOT_SEQUENCE_KIND: &'static str = "root_sequence_kind"; -pub const MERGE_SEQUENCES_OF_EVENTS: &'static str = "merge_sequences_of_events"; -pub const DISCOVER_EVENTS_GROUPS_IN_EACH_TRACE: &'static str = "discover_events_groups_in_each_trace"; -pub const SOFTWARE_DATA_EXTRACTION_CONFIG: &'static str = "software_data_extraction_config"; -pub const DISCOVER_ACTIVITY_INSTANCES_STRICT: &'static str = "discover_activity_instances_strict"; -pub const PUT_NOISE_EVENTS_IN_ONE_CLUSTER: &'static str = "put_noise_events_in_one_cluster"; -pub const OCEL_ANNOTATION: &'static str = "ocel_annotation"; +pub const EVENT_LOG: &str = "event_log"; +pub const ACTIVITIES: &str = "activities"; +pub const REPEAT_SETS: &str = "repeat_sets"; +pub const TRACE_ACTIVITIES: &str = "trace_activities"; +pub const PATTERNS: &str = "patterns"; +pub const PETRI_NET: &str = "petri_net"; +pub const ACTIVITIES_TO_LOGS: &str = "activities_to_logs"; +pub const ACTIVITY_NAME: &str = "activity_name"; +pub const HASHES_EVENT_LOG: &str = "hashes_event_log"; +pub const NAMES_EVENT_LOG: &str = "names_event_log"; +pub const COLORS_EVENT_LOG: &str = "colors_event_log"; +pub const COLORS_HOLDER: &str = "colors_holder"; +pub const GRAPH: &str = "graph"; +pub const GRAPHS: &str = "graphs"; +pub const PETRI_NET_COUNT_ANNOTATION: &str = "petri_net_count_annotation"; +pub const PETRI_NET_FREQUENCY_ANNOTATION: &str = "petri_net_frequency_annotation"; +pub const PETRI_NET_TRACE_FREQUENCY_ANNOTATION: &str = "petri_net_trace_frequency_annotation"; +pub const TRACES_ACTIVITIES_DATASET: &str = "traces_activities_dataset"; +pub const LABELED_TRACES_ACTIVITIES_DATASET: &str = "labeled_traces_activities_dataset"; +pub const ACTIVITIES_REPR_SOURCE: &str = "activities_repr_source"; +pub const DISTANCE: &str = "distance"; +pub const EXECUTE_ONLY_ON_LAST_EXTRACTION: &str = "execute_only_on_last_extraction"; +pub const LABELED_LOG_TRACES_DATASET: &str = "labeled_log_traces_dataset"; +pub const LOG_TRACES_DATASET: &str = "log_traces_dataset"; +pub const TRACES_REPR_SOURCE: &str = "traces_repr_source"; +pub const SYSTEM_METADATA: &str = "system_metadata"; +pub const LOG_SERIALIZATION_FORMAT: &str = "log_serialization_format"; +pub const GRAPH_TIME_ANNOTATION: &str = "graph_time_annotation"; +pub const ATTRIBUTE: &str = "attribute"; +pub const TIME_ANNOTATION_KIND: &str = "time_annotation_kind"; +pub const ATTRIBUTES: &str = "attributes"; +pub const PATHS: &str = "paths"; +pub const LOG_THREADS_DIAGRAM: &str = "log_threads_diagram"; +pub const THREAD_ATTRIBUTE: &str = "thread_attribute"; +pub const TIME_ATTRIBUTE: &str = "time_attribute"; +pub const TIME_DELTA: &str = "time_delta"; +pub const FEATURE_COUNT_KIND: &str = "feature_count_kind"; +pub const PERCENT_FROM_MAX_VALUE: &str = "percent_from_max_value"; +pub const TOLERANCES: &str = "tolerances"; +pub const MIN_POINTS_IN_CLUSTER_ARRAY: &str = "min_points_in_cluster_array"; +pub const EXECUTION_ID: &str = "execution_id"; +pub const ROOT_SEQUENCE_KIND: &str = "root_sequence_kind"; +pub const MERGE_SEQUENCES_OF_EVENTS: &str = "merge_sequences_of_events"; +pub const DISCOVER_EVENTS_GROUPS_IN_EACH_TRACE: &str = "discover_events_groups_in_each_trace"; +pub const SOFTWARE_DATA_EXTRACTION_CONFIG: &str = "software_data_extraction_config"; +pub const DISCOVER_ACTIVITY_INSTANCES_STRICT: &str = "discover_activity_instances_strict"; +pub const PUT_NOISE_EVENTS_IN_ONE_CLUSTER: &str = "put_noise_events_in_one_cluster"; +pub const OCEL_ANNOTATION: &str = "ocel_annotation"; #[macro_export] macro_rules! context_key { ($name:ident, $t:ty) => { paste::paste! { lazy_static! { - pub static ref [<$name _KEY>]: crate::utils::context_key::DefaultContextKey<$t> = crate::utils::context_key::DefaultContextKey::new($name); + pub static ref [<$name _KEY>]: $crate::utils::context_key::DefaultContextKey<$t> = $crate::utils::context_key::DefaultContextKey::new($name); } } }; diff --git a/Ficus/src/rust/ficus/src/pipelines/multithreading.rs b/Ficus/src/rust/ficus/src/pipelines/multithreading.rs index b04f3f045..b25a8eaf4 100644 --- a/Ficus/src/rust/ficus/src/pipelines/multithreading.rs +++ b/Ficus/src/rust/ficus/src/pipelines/multithreading.rs @@ -11,18 +11,19 @@ use crate::{ analysis::log_info::event_log_info::create_threads_log_by_attribute, clustering::traces::dbscan::clusterize_log_by_traces_dbscan, discovery::{ + ecfg::log_prepare::prepare_software_log, multithreaded_dfg::dfg::{ - discover_multithreaded_dfg, enumerate_multithreaded_events_groups, MultithreadedTracePartsCreationStrategy, + MultithreadedTracePartsCreationStrategy, discover_multithreaded_dfg, enumerate_multithreaded_events_groups, }, - root_sequence::log_prepare::prepare_software_log, timeline::{ abstraction::abstract_event_groups, discovery::{discover_timeline_diagram, discover_traces_timeline_diagram}, - events_groups::{enumerate_event_groups, EventGroup}, + events_groups::{EventGroup, enumerate_event_groups}, software_data::extraction_config::{ExtractionConfig, MethodStartEndConfig, SoftwareDataExtractionConfig}, }, }, }, + pipeline_part, pipelines::{ context::{PipelineContext, PipelineInfrastructure}, errors::pipeline_errors::{PipelinePartExecutionError, RawPartExecutionError}, @@ -63,8 +64,9 @@ impl FromStr for FeatureCountKindDto { } impl PipelineParts { - pub(super) fn discover_log_threads_diagram() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_LOG_TIMELINE_DIAGRAM, &|context, _, config| { + pipeline_part!( + discover_log_timeline_diagram, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; let thread_attribute = Self::get_user_data(config, &THREAD_ATTRIBUTE_KEY)?; let time_attribute = Self::get_user_data(config, &TIME_ATTRIBUTE_KEY).ok(); @@ -75,10 +77,7 @@ impl PipelineParts { log, thread_attribute.as_str(), time_attribute, - match event_group_delta { - None => None, - Some(delta) => Some(*delta as u64), - }, + event_group_delta.map(|delta| *delta as u64), Self::get_control_flow_regexes(&software_data_extraction_config)?.as_ref(), ); @@ -88,8 +87,8 @@ impl PipelineParts { } Ok(()) - }) - } + } + ); fn get_control_flow_regexes(config: &SoftwareDataExtractionConfig) -> Result>, PipelinePartExecutionError> { config @@ -97,18 +96,17 @@ impl PipelineParts { .map_err(|message| PipelinePartExecutionError::Raw(RawPartExecutionError::new(message))) } - pub(super) fn create_threads_log() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::CREATE_THREADS_LOG, &|context, _, config| { - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - let thread_attribute = Self::get_user_data(config, &THREAD_ATTRIBUTE_KEY)?; - context.put_concrete(EVENT_LOG_KEY.key(), create_threads_log_by_attribute(log, thread_attribute)); + pipeline_part!(create_threads_log, |context: &mut PipelineContext, _, config: &UserDataImpl| { + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + let thread_attribute = Self::get_user_data(config, &THREAD_ATTRIBUTE_KEY)?; + context.put_concrete(EVENT_LOG_KEY.key(), create_threads_log_by_attribute(log, thread_attribute)); - Ok(()) - }) - } + Ok(()) + }); - pub(super) fn abstract_timeline_diagram() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::ABSTRACT_TIMELINE_DIAGRAM, &|context, infra, config| { + pipeline_part!( + abstract_timeline_diagram, + |context: &mut PipelineContext, infra: &PipelineInfrastructure, config: &UserDataImpl| { let (thread_attribute, time_attribute) = Self::extract_thread_and_time_attribute(context)?; Self::abstract_event_groups( @@ -119,8 +117,8 @@ impl PipelineParts { thread_attribute, time_attribute, ) - }) - } + } + ); fn create_event_groups_from_timeline(context: &PipelineContext) -> Result>, PipelinePartExecutionError> { let timeline = Self::get_user_data(context, &LOG_THREADS_DIAGRAM_KEY)?; @@ -150,12 +148,9 @@ impl PipelineParts { let put_noise_events_in_one_cluster = *Self::get_user_data(config, &PUT_NOISE_EVENTS_IN_ONE_CLUSTER_KEY)?; let (_, labeled_dataset) = - match clusterize_log_by_traces_dbscan(&mut params, tolerance, min_points_in_cluster, put_noise_events_in_one_cluster) { - Ok(new_logs) => new_logs, - Err(error) => return Err(error.into()), - }; + clusterize_log_by_traces_dbscan(&mut params, tolerance, min_points_in_cluster, put_noise_events_in_one_cluster)?; - if let Some(after_clusterization_pipeline) = Self::get_user_data(config, &PIPELINE_KEY).ok() { + if let Ok(after_clusterization_pipeline) = Self::get_user_data(config, &PIPELINE_KEY) { let abstracted_log = abstract_event_groups( events_groups, labeled_dataset.labels(), @@ -175,8 +170,9 @@ impl PipelineParts { Ok(()) } - pub fn abstract_multithreaded_events_groups() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::ABSTRACT_MULTITHREADED_EVENTS_GROUPS, &|context, infra, config| { + pipeline_part!( + abstract_multithreaded_events_groups, + |context: &mut PipelineContext, infra: &PipelineInfrastructure, config: &UserDataImpl| { let thread_attribute = Self::get_user_data(config, &THREAD_ATTRIBUTE_KEY)?.to_owned(); let time_attribute = Self::get_user_data(config, &TIME_ATTRIBUTE_KEY).ok().cloned(); let software_config = Self::get_software_data_extraction_config(context); @@ -185,11 +181,11 @@ impl PipelineParts { let strategy = Self::create_multithreaded_trace_parts_creation_strategy(config)?; let groups = enumerate_multithreaded_events_groups(log, &software_config, thread_attribute.as_str(), &strategy) - .map_err(|e| PipelinePartExecutionError::new_raw(e))?; + .map_err(PipelinePartExecutionError::new_raw)?; Self::abstract_event_groups(groups, context, config, infra, thread_attribute, time_attribute) - }) - } + } + ); fn get_software_data_extraction_config(context: &PipelineContext) -> SoftwareDataExtractionConfig { match Self::get_user_data(context, &SOFTWARE_DATA_EXTRACTION_CONFIG_KEY) { @@ -216,8 +212,9 @@ impl PipelineParts { log } - pub(super) fn discover_traces_timeline_diagram() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_TRACES_TIMELINE_DIAGRAM, &|context, _, config| { + pipeline_part!( + discover_traces_timeline_diagram, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let time_attribute = Self::get_user_data(config, &TIME_ATTRIBUTE_KEY).ok(); let event_group_delta = Self::get_user_data(config, &TIME_DELTA_KEY).ok(); let discover_events_groups_in_each_trace = Self::get_user_data(config, &DISCOVER_EVENTS_GROUPS_IN_EACH_TRACE_KEY)?; @@ -227,10 +224,7 @@ impl PipelineParts { let diagram = discover_traces_timeline_diagram( log, time_attribute, - match event_group_delta { - None => None, - Some(delta) => Some(*delta as u64), - }, + event_group_delta.map(|delta| *delta as u64), *discover_events_groups_in_each_trace, Self::get_control_flow_regexes(&software_data_extraction_config)?.as_ref(), ); @@ -241,11 +235,12 @@ impl PipelineParts { } Ok(()) - }) - } + } + ); - pub(super) fn prepare_software_log() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::PREPARE_SOFTWARE_EVENT_LOG, &|context, _, config| { + pipeline_part!( + prepare_software_event_log, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; let software_data_extraction_config = Self::get_software_data_extraction_config(context); let time_attribute = Self::get_user_data(config, &TIME_ATTRIBUTE_KEY).ok(); @@ -258,45 +253,42 @@ impl PipelineParts { context.put_concrete(EVENT_LOG_KEY.key(), prepared_log); Ok(()) - }) - } + } + ); - pub(super) fn shorten_allocation_types() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::SHORTEN_ALLOCATION_TYPE, &|context, _, _| { - let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; - let software_data_extraction_config = Self::get_software_data_extraction_config(context); - if let Some(config) = software_data_extraction_config.allocation() { - let alloc_regex = config.event_class_regex(); - let alloc_regex = match Regex::new(alloc_regex) { - Ok(regex) => regex, - Err(err) => { - return Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(format!( - "Failed to create regex from {}, error: {}", - alloc_regex, - err.to_string() - )))) - } - }; + pipeline_part!(shorten_allocation_type, |context: &mut PipelineContext, _, _| { + let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; + let software_data_extraction_config = Self::get_software_data_extraction_config(context); + if let Some(config) = software_data_extraction_config.allocation() { + let alloc_regex = config.event_class_regex(); + let alloc_regex = match Regex::new(alloc_regex) { + Ok(regex) => regex, + Err(err) => { + return Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(format!( + "Failed to create regex from {}, error: {}", + alloc_regex, err + )))); + } + }; - for trace in log.traces() { - let trace = trace.borrow_mut(); - for event in trace.events() { - if alloc_regex.is_match(event.borrow().name().as_str()).unwrap_or(false) { - let mut event = event.borrow_mut(); - if let Some(map) = event.payload_map_mut() { - if let Some(type_name) = map.get_mut(config.info().type_name_attr().as_str()) { - let string = type_name.to_string_repr().to_string(); - *type_name = EventPayloadValue::String(Rc::new(Box::new(Self::shorten_type_or_method_name(string)))); - } - } + for trace in log.traces() { + let trace = trace.borrow_mut(); + for event in trace.events() { + if alloc_regex.is_match(event.borrow().name().as_str()).unwrap_or(false) { + let mut event = event.borrow_mut(); + if let Some(map) = event.payload_map_mut() + && let Some(type_name) = map.get_mut(config.info().type_name_attr().as_str()) + { + let string = type_name.to_string_repr().to_string(); + *type_name = EventPayloadValue::String(Rc::new(Box::new(Self::shorten_type_or_method_name(string)))); } } } } + } - Ok(()) - }) - } + Ok(()) + }); fn shorten_type_or_method_name(name: String) -> String { let mut result = String::new(); @@ -308,7 +300,7 @@ impl PipelineParts { result.push_str(last_seen_word.as_str()); last_seen_word.clear(); - while let Some(char) = chars.next() { + for char in chars.by_ref() { if char == '[' { result.push('['); continue 'main_loop; @@ -343,59 +335,57 @@ impl PipelineParts { result } - pub(super) fn shorten_methods_names() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::SHORTEN_METHOD_NAMES, &|context, _, _| { - let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; + pipeline_part!(shorten_method_names, |context: &mut PipelineContext, _, _| { + let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; - let methods_id_factories: Vec<&dyn Fn(&String, &String, &String) -> String> = vec![ - &|_, name, _| name.to_owned(), - &|_, name, signature| name.to_owned() + signature, - &|namespace, name, _| namespace.to_string() + name, - ]; + let methods_id_factories: Vec<&dyn Fn(&String, &String, &String) -> String> = vec![ + &|_, name, _| name.to_owned(), + &|_, name, signature| name.to_owned() + signature, + &|namespace, name, _| namespace.to_string() + name, + ]; - let configs = Self::create_processed_method_extraction_configs(context); - if configs.is_empty() { - return Ok(()); - } + let configs = Self::create_processed_method_extraction_configs(context); + if configs.is_empty() { + return Ok(()); + } - for config in &configs { - for method_id_factory in &methods_id_factories { - if Self::check_if_can_use_method_id(log, config, method_id_factory) { - for trace in log.traces() { - let trace = trace.borrow_mut(); - for event in trace.events() { - let mut event = event.borrow_mut(); - let name = if let Some(payload) = event.payload_map() { - if let Some((namespace, name, signature)) = Self::extract_method_name_parts(payload, config) { - method_id_factory(&namespace, &name, &signature) - } else { - continue; - } + for config in &configs { + for method_id_factory in &methods_id_factories { + if Self::check_if_can_use_method_id(log, config, method_id_factory) { + for trace in log.traces() { + let trace = trace.borrow_mut(); + for event in trace.events() { + let mut event = event.borrow_mut(); + let name = if let Some(payload) = event.payload_map() { + if let Some((namespace, name, signature)) = Self::extract_method_name_parts(payload, config) { + method_id_factory(&namespace, &name, &signature) } else { continue; - }; + } + } else { + continue; + }; - event.set_name(name); - } + event.set_name(name); } - - return Ok(()); } + + return Ok(()); } + } - for trace in log.traces() { - let trace = trace.borrow_mut(); - for event in trace.events() { - if config.event_regex.is_match(event.borrow().name().as_str()).unwrap_or(false) { - Self::shorten_method_name(config, &mut event.borrow_mut()); - } + for trace in log.traces() { + let trace = trace.borrow_mut(); + for event in trace.events() { + if config.event_regex.is_match(event.borrow().name().as_str()).unwrap_or(false) { + Self::shorten_method_name(config, &mut event.borrow_mut()); } } } + } - Ok(()) - }) - } + Ok(()) + }); fn create_processed_method_extraction_configs(context: &PipelineContext) -> Vec { let software_data_extraction_config = Self::get_software_data_extraction_config(context); @@ -485,18 +475,18 @@ impl PipelineParts { continue; } - if let Some(payload) = event.payload_map() { - if let Some((namespace, name, signature)) = Self::extract_method_name_parts(payload, config) { - let id = method_id_factory(&namespace, &name, &signature); - let fqn = namespace + name.as_str() + signature.as_str(); - - if let Some(entry) = map.get(&id) { - if !fqn.eq(entry) { - return false; - } - } else { - map.insert(id, fqn); + if let Some(payload) = event.payload_map() + && let Some((namespace, name, signature)) = Self::extract_method_name_parts(payload, config) + { + let id = method_id_factory(&namespace, &name, &signature); + let fqn = namespace + name.as_str() + signature.as_str(); + + if let Some(entry) = map.get(&id) { + if !fqn.eq(entry) { + return false; } + } else { + map.insert(id, fqn); } } } @@ -505,46 +495,42 @@ impl PipelineParts { true } - pub(super) fn set_methods_display_name() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::SET_METHODS_DISPLAY_NAME, &|context, _, _| { - let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; - let configs = Self::create_processed_method_extraction_configs(context); - - for trace in log.traces() { - let trace = trace.borrow(); - for event in trace.events() { - let mut display_name = None; - if let Some(payload) = event.borrow().payload_map() { - for config in &configs { - if config.event_regex.is_match(event.borrow().name().as_str()).unwrap_or(false) { - if let Some((_, name, _)) = Self::extract_method_name_parts(payload, config) { - display_name = Some(match config.prefix.as_ref() { - None => name, - Some(prefix) => prefix.to_string() + name.as_str(), - }); - } - } + pipeline_part!(set_methods_display_name, |context: &mut PipelineContext, _, _| { + let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; + let configs = Self::create_processed_method_extraction_configs(context); + + for trace in log.traces() { + let trace = trace.borrow(); + for event in trace.events() { + let mut display_name = None; + if let Some(payload) = event.borrow().payload_map() { + for config in &configs { + if config.event_regex.is_match(event.borrow().name().as_str()).unwrap_or(false) + && let Some((_, name, _)) = Self::extract_method_name_parts(payload, config) + { + display_name = Some(match config.prefix.as_ref() { + None => name, + Some(prefix) => prefix.to_string() + name.as_str(), + }); } } + } - if let Some(display_name) = display_name { - event - .borrow_mut() - .user_data_mut() - .put_concrete(DISPLAY_NAME_KEY.key(), display_name); - } + if let Some(display_name) = display_name { + event + .borrow_mut() + .user_data_mut() + .put_concrete(DISPLAY_NAME_KEY.key(), display_name); } } + } - Ok(()) - }) - } + Ok(()) + }); - pub(super) fn remain_only_method_start_events() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::REMAIN_ONLY_METHOD_START_EVENTS, &|context, _, _| { - Self::remain_only_method_start_or_end_events(context, true) - }) - } + pipeline_part!(remain_only_method_start_events, |context: &mut PipelineContext, _, _| { + Self::remain_only_method_start_or_end_events(context, true) + }); fn remain_only_method_start_or_end_events( context: &PipelineContext, @@ -564,14 +550,13 @@ impl PipelineParts { Ok(()) } - pub(super) fn remain_only_method_end_events() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::REMAIN_ONLY_METHOD_END_EVENTS, &|context, _, _| { - Self::remain_only_method_start_or_end_events(context, false) - }) - } + pipeline_part!(remain_only_method_end_events, |context: &mut PipelineContext, _, _| { + Self::remain_only_method_start_or_end_events(context, false) + }); - pub(super) fn discover_multithreaded_dfg() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_MULTITHREADED_DFG, &|context, _, config| { + pipeline_part!( + discover_multithreaded_dfg, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; let thread_attribute = Self::get_user_data(config, &THREAD_ATTRIBUTE_KEY)?; let strategy = Self::create_multithreaded_trace_parts_creation_strategy(config)?; @@ -580,8 +565,8 @@ impl PipelineParts { context.put_concrete(GRAPH_KEY.key(), dfg); Ok(()) - }) - } + } + ); fn create_multithreaded_trace_parts_creation_strategy( config: &UserDataImpl, diff --git a/Ficus/src/rust/ficus/src/pipelines/mutations_parts.rs b/Ficus/src/rust/ficus/src/pipelines/mutations_parts.rs index dcf2f34c7..cf1c0103c 100644 --- a/Ficus/src/rust/ficus/src/pipelines/mutations_parts.rs +++ b/Ficus/src/rust/ficus/src/pipelines/mutations_parts.rs @@ -1,5 +1,6 @@ use crate::{ features::mutations::mutations::{add_artificial_start_end_activities, append_attributes_to_name}, + pipeline_part, pipelines::{ context::PipelineContext, errors::pipeline_errors::PipelinePartExecutionError, @@ -11,11 +12,10 @@ use crate::{ }; impl PipelineParts { - pub(super) fn add_artificial_start_end_events() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::ADD_ARTIFICIAL_START_END_EVENTS, &|context, _, config| { - Self::create_add_start_end_events_internal(context, config, true, true) - }) - } + pipeline_part!( + add_artificial_start_end_events, + |context: &mut PipelineContext, _, config: &UserDataImpl| { Self::create_add_start_end_events_internal(context, config, true, true) } + ); fn create_add_start_end_events_internal( context: &mut PipelineContext, @@ -25,7 +25,7 @@ impl PipelineParts { ) -> Result<(), PipelinePartExecutionError> { let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; let attributes_to_copy = match Self::get_user_data(config, &ATTRIBUTES_KEY) { - Ok(attributes_to_copy) => Some(attributes_to_copy.iter().map(|a| a.clone()).collect()), + Ok(attributes_to_copy) => Some(attributes_to_copy.to_vec()), Err(_) => None, }; @@ -34,26 +34,25 @@ impl PipelineParts { Ok(()) } - pub(super) fn add_artificial_start_events() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::ADD_ARTIFICIAL_START_EVENTS, &|context, _, config| { - Self::create_add_start_end_events_internal(context, config, true, false) - }) - } + pipeline_part!( + add_artificial_start_events, + |context: &mut PipelineContext, _, config: &UserDataImpl| { Self::create_add_start_end_events_internal(context, config, true, false) } + ); - pub(super) fn add_artificial_end_events() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::ADD_ARTIFICIAL_END_EVENTS, &|context, _, config| { - Self::create_add_start_end_events_internal(context, config, false, true) - }) - } + pipeline_part!( + add_artificial_end_events, + |context: &mut PipelineContext, _, config: &UserDataImpl| { Self::create_add_start_end_events_internal(context, config, false, true) } + ); - pub(super) fn append_attributes_to_name() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::APPEND_ATTRIBUTES_TO_NAME, &|context, _, config| { + pipeline_part!( + append_attributes_to_name, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; let attributes = Self::get_user_data(config, &ATTRIBUTES_KEY)?; append_attributes_to_name(log, attributes); Ok(()) - }) - } + } + ); } diff --git a/Ficus/src/rust/ficus/src/pipelines/parts_names.rs b/Ficus/src/rust/ficus/src/pipelines/parts_names.rs index 3f2704427..45af14388 100644 --- a/Ficus/src/rust/ficus/src/pipelines/parts_names.rs +++ b/Ficus/src/rust/ficus/src/pipelines/parts_names.rs @@ -27,7 +27,7 @@ impl PipelineParts { pub const GET_NAMES_EVENT_LOG: &'static str = "GetNamesEventLog"; pub const GET_HASHES_EVENT_LOG: &'static str = "GetHashesEventLog"; pub const USE_NAMES_EVENT_LOG: &'static str = "UseNamesEventLog"; - pub const DISCOVER_ACTIVITIES_FOR_SEVERAL_LEVEL: &'static str = "DiscoverActivitiesForSeveralLevels"; + pub const DISCOVER_ACTIVITIES_FOR_SEVERAL_LEVELS: &'static str = "DiscoverActivitiesForSeveralLevels"; pub const DISCOVER_ACTIVITIES_IN_UNATTACHED_SUBTRACES: &'static str = "DiscoverActivitiesInUnattachedSubTraces"; pub const DISCOVER_ACTIVITIES_UNTIL_NO_MORE: &'static str = "DiscoverActivitiesUntilNoMore"; pub const EXECUTE_WITH_EACH_ACTIVITY_LOG: &'static str = "ExecuteWithEachActivityLog"; @@ -55,7 +55,7 @@ impl PipelineParts { pub const DISCOVER_DFG_STREAM: &'static str = "DiscoverDirectlyFollowsGraphStream"; pub const CREATE_THREADS_LOG: &'static str = "CreateThreadsLog"; pub const ABSTRACT_TIMELINE_DIAGRAM: &'static str = "AbstractTimelineDiagram"; - pub const DISCOVER_ROOT_SEQUENCE_GRAPH: &'static str = "DiscoverRootSequenceGraph"; + pub const DISCOVER_ECFG: &'static str = "DiscoverECFG"; pub const DISCOVER_LOOPS_STRICT: &'static str = "DiscoverLoopsStrict"; pub const DISCOVER_TRACES_TIMELINE_DIAGRAM: &'static str = "DiscoverTracesTimelineDiagram"; diff --git a/Ficus/src/rust/ficus/src/pipelines/patterns_parts.rs b/Ficus/src/rust/ficus/src/pipelines/patterns_parts.rs index 61e9b6e32..debf6f1c7 100644 --- a/Ficus/src/rust/ficus/src/pipelines/patterns_parts.rs +++ b/Ficus/src/rust/ficus/src/pipelines/patterns_parts.rs @@ -2,10 +2,10 @@ use super::{context::PipelineContext, errors::pipeline_errors::PipelinePartExecu use crate::{ features::analysis::patterns::{ contexts::PatternsDiscoveryStrategy, - pattern_info::{UnderlyingPatternKind, UNDERLYING_PATTERN_KIND_KEY}, + pattern_info::{UNDERLYING_PATTERN_KIND_KEY, UnderlyingPatternKind}, repeats::{find_maximal_repeats, find_near_super_maximal_repeats, find_super_maximal_repeats}, strict_loops::find_loops_strict, - tandem_arrays::{find_maximal_tandem_arrays, find_primitive_tandem_arrays, SubArrayInTraceInfo}, + tandem_arrays::{SubArrayInTraceInfo, find_maximal_tandem_arrays, find_primitive_tandem_arrays}, }, pipelines::{ keys::context_keys::{ @@ -28,9 +28,9 @@ pub enum PatternsKindDto { NearSuperMaximalRepeats, } -impl Into for PatternsKindDto { - fn into(self) -> UnderlyingPatternKind { - match self { +impl From for UnderlyingPatternKind { + fn from(val: PatternsKindDto) -> Self { + match val { PatternsKindDto::PrimitiveTandemArrays => UnderlyingPatternKind::PrimitiveTandemArray, PatternsKindDto::MaximalTandemArrays => UnderlyingPatternKind::MaximalTandemArray, PatternsKindDto::MaximalRepeats => UnderlyingPatternKind::MaximalRepeat, @@ -88,7 +88,7 @@ impl PipelineParts { Self::create_pipeline_part(Self::FIND_PRIMITIVE_TANDEM_ARRAYS, &|context, _, config| { Self::find_tandem_arrays_and_put_to_context( context, - &config, + config, find_primitive_tandem_arrays, UnderlyingPatternKind::PrimitiveTandemArray, ) @@ -99,7 +99,7 @@ impl PipelineParts { Self::create_pipeline_part(Self::FIND_MAXIMAL_TANDEM_ARRAYS, &|context, _, config| { Self::find_tandem_arrays_and_put_to_context( context, - &config, + config, find_maximal_tandem_arrays, UnderlyingPatternKind::MaximalTandemArray, ) @@ -137,7 +137,7 @@ impl PipelineParts { let hashed_log = Self::create_hashed_event_log(config, log); - let repeats = patterns_finder(&hashed_log, &strategy); + let repeats = patterns_finder(&hashed_log, strategy); context.put_concrete(UNDERLYING_PATTERN_KIND_KEY.key(), underlying_pattern_kind); context.put_concrete(HASHES_EVENT_LOG_KEY.key(), hashed_log); diff --git a/Ficus/src/rust/ficus/src/pipelines/pipeline_parts.rs b/Ficus/src/rust/ficus/src/pipelines/pipeline_parts.rs index 54ee16d9a..40f199897 100644 --- a/Ficus/src/rust/ficus/src/pipelines/pipeline_parts.rs +++ b/Ficus/src/rust/ficus/src/pipelines/pipeline_parts.rs @@ -41,6 +41,25 @@ impl PipelineParts { unsafe impl Sync for PipelineParts {} unsafe impl Send for PipelineParts {} +#[macro_export] +macro_rules! pipeline_part { + ($name:ident, $body:expr) => { + paste::item! { + pub(super) fn $name () -> (String, PipelinePartFactory) { + Self::create_pipeline_part(Self::[<$name:upper>], &|context, infra, config| { + $body(context, infra, config) + }) + } + } + }; +} + +impl Default for PipelineParts { + fn default() -> Self { + Self::new() + } +} + impl PipelineParts { pub fn new() -> Self { let parts = vec![ @@ -54,23 +73,23 @@ impl PipelineParts { Self::discover_activities(), Self::discover_activities_instances(), Self::create_log_from_activities(), - Self::filter_log_by_event_name(), - Self::filter_log_by_regex(), + Self::filter_events_by_name(), + Self::filter_events_by_regex(), Self::remain_events_by_regex(), Self::filter_log_by_variants(), - Self::draw_placements_of_event_by_name(), - Self::draw_events_placements_by_regex(), + Self::draw_placement_of_event_by_name(), + Self::draw_placement_of_event_by_regex(), Self::draw_full_activities_diagram(), Self::draw_short_activities_diagram(), Self::get_event_log_info(), - Self::clear_activities_related_stuff(), - Self::get_number_of_underlying_events(), - Self::filter_traces_by_count(), + Self::clear_activities(), + Self::get_underlying_events_count(), + Self::filter_traces_by_events_count(), Self::traces_diversity_diagram(), Self::get_names_event_log(), Self::get_hashes_event_log(), Self::use_names_event_log(), - Self::discover_activities_instances_for_several_levels(), + Self::discover_activities_for_several_levels(), Self::discover_activities_in_unattached_subtraces(), Self::discover_activities_until_no_more(), Self::execute_with_each_activity_log(), @@ -85,45 +104,45 @@ impl PipelineParts { Self::discover_petri_net_alpha_plus(), Self::discover_petri_net_alpha_plus_plus(), Self::discover_petri_net_alpha_plus_plus_nfc(), - Self::discover_directly_follows_graph(), - Self::discover_petri_net_heuristic_miner(), + Self::discover_dfg(), + Self::discover_petri_net_heuristic(), Self::discover_fuzzy_graph(), Self::annotate_petri_net_count(), Self::annotate_petri_net_frequency(), Self::annotate_petri_net_trace_frequency(), Self::ensure_initial_marking(), Self::read_log_from_bxes(), - Self::clusterize_activities_from_traces_k_means(), - Self::clusterize_activities_from_traces_k_means_grid_search(), + Self::clusterize_activities_from_traces_kmeans(), + Self::clusterize_activities_from_traces_kmeans_grid_search(), Self::clusterize_activities_from_traces_dbscan(), Self::create_traces_activities_dataset(), Self::write_log_to_bxes(), Self::clusterize_log_traces(), Self::serialize_activities_logs(), - Self::read_xes_from_bytes(), - Self::read_bxes_from_bytes(), - Self::write_bxes_to_bytes(), - Self::write_xes_to_bytes(), + Self::read_xes_log_from_bytes(), + Self::read_bxes_log_from_bytes(), + Self::write_bxes_log_to_bytes(), + Self::write_xes_log_to_bytes(), Self::reverse_hierarchy_indices(), Self::discover_cases(), - Self::annotate_graph_with_time_performance(), - Self::draw_traces_diversity_diagram_by_attribute(), - Self::discover_directly_follows_graph_by_attribute(), + Self::annotate_graph_with_time(), + Self::traces_diversity_diagram_by_attribute(), + Self::discover_dfg_by_attribute(), Self::append_attributes_to_name(), Self::merge_xes_logs_from_paths(), - Self::discover_directly_follows_graph_stream(), + Self::discover_dfg_stream(), Self::discover_petri_net_alpha_stream(), - Self::discover_log_threads_diagram(), + Self::discover_log_timeline_diagram(), Self::create_threads_log(), Self::abstract_timeline_diagram(), - Self::clusterize_log_by_traces_k_means_grid_search(), + Self::clusterize_log_traces_k_means_grid_search(), Self::clusterize_log_traces_dbscan_grid_search(), - Self::discover_root_sequence_graph(), + Self::discover_ecfg(), Self::discover_loops_strict(), Self::discover_traces_timeline_diagram(), - Self::prepare_software_log(), - Self::shorten_allocation_types(), - Self::shorten_methods_names(), + Self::prepare_software_event_log(), + Self::shorten_allocation_type(), + Self::shorten_method_names(), Self::set_methods_display_name(), Self::remain_only_method_start_events(), Self::remain_only_method_end_events(), @@ -138,7 +157,7 @@ impl PipelineParts { let mut names_to_parts = HashMap::new(); for part in parts { - let prev = names_to_parts.insert((&part.0).to_owned(), part.1); + let prev = names_to_parts.insert(part.0.to_owned(), part.1); assert!(prev.is_none()); } @@ -152,7 +171,7 @@ impl PipelineParts { pub fn pipeline_parts_descriptors(&self) -> Vec { let mut descriptors = vec![]; for factory in self.names_to_parts.values() { - let name = factory(Box::new(UserDataImpl::new())).name().to_owned(); + let name = factory(Box::default()).name().to_owned(); descriptors.push(PipelinePartDescriptor::new(name)) } diff --git a/Ficus/src/rust/ficus/src/pipelines/pipelines.rs b/Ficus/src/rust/ficus/src/pipelines/pipelines.rs index 142fce32a..25ba3b1d4 100644 --- a/Ficus/src/rust/ficus/src/pipelines/pipelines.rs +++ b/Ficus/src/rust/ficus/src/pipelines/pipelines.rs @@ -36,7 +36,7 @@ impl PipelinePart for Pipeline { impl Pipeline { fn put_default_concrete_keys(&self, context: &mut PipelineContext) { - if let None = context.concrete(COLORS_HOLDER_KEY.key()) { + if context.concrete(COLORS_HOLDER_KEY.key()).is_none() { context.put_concrete(COLORS_HOLDER_KEY.key(), ColorsHolder::empty()); } } diff --git a/Ficus/src/rust/ficus/src/pipelines/util_parts.rs b/Ficus/src/rust/ficus/src/pipelines/util_parts.rs index 14775813d..e645e8a2c 100644 --- a/Ficus/src/rust/ficus/src/pipelines/util_parts.rs +++ b/Ficus/src/rust/ficus/src/pipelines/util_parts.rs @@ -16,10 +16,12 @@ use crate::{ xes::{xes_event::XesEventImpl, xes_event_log::XesEventLogImpl, xes_trace::XesTraceImpl}, }, features::analysis::log_info::{event_log_info::OfflineEventLogInfo, log_info_creation_dto::EventLogInfoCreationDto}, + pipeline_part, pipelines::{ + context::{PipelineContext, PipelineInfrastructure}, errors::pipeline_errors::PipelinePartExecutionError, keys::context_keys::{ - EVENT_CLASS_REGEX_KEY, EVENT_LOG_INFO_KEY, EVENT_LOG_KEY, GRAPHS_KEY, GRAPH_KEY, HASHES_EVENT_LOG_KEY, NAMES_EVENT_LOG_KEY, + EVENT_CLASS_REGEX_KEY, EVENT_LOG_INFO_KEY, EVENT_LOG_KEY, GRAPH_KEY, GRAPHS_KEY, HASHES_EVENT_LOG_KEY, NAMES_EVENT_LOG_KEY, PIPELINE_KEY, }, pipeline_parts::PipelineParts, @@ -38,125 +40,110 @@ impl PipelineParts { let hasher = RegexEventHasher::new(regex).ok().unwrap(); log.to_hashes_event_log(&hasher) } - Err(_) => log.to_hashes_event_log(&NameEventHasher::new()), + Err(_) => log.to_hashes_event_log(&NameEventHasher), } } - pub(super) fn get_event_log_info() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::GET_EVENT_LOG_INFO, &|context, _, _| { - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - let log_info = OfflineEventLogInfo::create_from(EventLogInfoCreationDto::default(log)); - context.put_concrete(EVENT_LOG_INFO_KEY.key(), log_info); + pipeline_part!(get_event_log_info, |context: &mut PipelineContext, _, _| { + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + let log_info = OfflineEventLogInfo::create_from(EventLogInfoCreationDto::default(log)); + context.put_concrete(EVENT_LOG_INFO_KEY.key(), log_info); - Ok(()) - }) - } + Ok(()) + }); - pub(super) fn get_hashes_event_log() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::GET_HASHES_EVENT_LOG, &|context, _, config| { - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - let hashes_event_log = Self::create_hashed_event_log(config, log); + pipeline_part!(get_hashes_event_log, |context: &mut PipelineContext, _, config: &UserDataImpl| { + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + let hashes_event_log = Self::create_hashed_event_log(config, log); - context.put_concrete(HASHES_EVENT_LOG_KEY.key(), hashes_event_log); - - Ok(()) - }) - } + context.put_concrete(HASHES_EVENT_LOG_KEY.key(), hashes_event_log); - pub(super) fn get_names_event_log() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::GET_NAMES_EVENT_LOG, &|context, _, _| { - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + Ok(()) + }); - let mut result = vec![]; - for trace in log.traces() { - let mut vec = vec![]; - for event in trace.borrow().events() { - vec.push(event.borrow().name().to_string()); - } + pipeline_part!(get_names_event_log, |context: &mut PipelineContext, _, _| { + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - result.push(vec); + let mut result = vec![]; + for trace in log.traces() { + let mut vec = vec![]; + for event in trace.borrow().events() { + vec.push(event.borrow().name().to_string()); } - context.put_concrete(NAMES_EVENT_LOG_KEY.key(), result); + result.push(vec); + } - Ok(()) - }) - } + context.put_concrete(NAMES_EVENT_LOG_KEY.key(), result); - pub(super) fn use_names_event_log() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::USE_NAMES_EVENT_LOG, &|context, _, _| { - let names_log = Self::get_user_data(context, &NAMES_EVENT_LOG_KEY)?; - let mut log = XesEventLogImpl::empty(); - for names_trace in names_log { - let mut trace = XesTraceImpl::empty(); - let mut date = DateTime::::MIN_UTC; - - for name in names_trace { - let event = XesEventImpl::new(name.clone(), date.clone()); - trace.push(Rc::new(RefCell::new(event))); - date = date + Duration::seconds(1); - } - - log.push(Rc::new(RefCell::new(trace))); + Ok(()) + }); + + pipeline_part!(use_names_event_log, |context: &mut PipelineContext, _, _| { + let names_log = Self::get_user_data(context, &NAMES_EVENT_LOG_KEY)?; + let mut log = XesEventLogImpl::empty(); + for names_trace in names_log { + let mut trace = XesTraceImpl::empty(); + let mut date = DateTime::::MIN_UTC; + + for name in names_trace { + let event = XesEventImpl::new(name.clone(), date); + trace.push(Rc::new(RefCell::new(event))); + date += Duration::seconds(1); } - context.put_concrete::(EVENT_LOG_KEY.key(), log); + log.push(Rc::new(RefCell::new(trace))); + } - Ok(()) - }) - } + context.put_concrete::(EVENT_LOG_KEY.key(), log); + + Ok(()) + }); - pub(super) fn execute_frontend_pipeline() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::EXECUTE_FRONTEND_PIPELINE, &|context, infra, config| { + pipeline_part!( + execute_frontend_pipeline, + |context: &mut PipelineContext, infra: &PipelineInfrastructure, config: &UserDataImpl| { let pipeline = Self::get_user_data(config, &PIPELINE_KEY)?; pipeline.execute(context, infra)?; Ok(()) - }) - } + } + ); - pub(super) fn merge_graphs() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::MERGE_GRAPHS, &|context, _, _| { - let graphs = Self::get_user_data(context, &GRAPHS_KEY)?; + pipeline_part!(merge_graphs, |context: &mut PipelineContext, _, _| { + let graphs = Self::get_user_data(context, &GRAPHS_KEY)?; - let graph = merge_graphs(graphs).map_err(|e| PipelinePartExecutionError::new_raw(e.to_string()))?; - context.put_concrete(GRAPH_KEY.key(), graph); + let graph = merge_graphs(graphs).map_err(|e| PipelinePartExecutionError::new_raw(e.to_string()))?; + context.put_concrete(GRAPH_KEY.key(), graph); - Ok(()) - }) - } + Ok(()) + }); - pub(super) fn add_graph_to_graphs() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::ADD_GRAPH_TO_GRAPHS, &|context, _, _| { - let graph = Self::get_user_data(context, &GRAPH_KEY)?.clone(); + pipeline_part!(add_graph_to_graphs, |context: &mut PipelineContext, _, _| { + let graph = Self::get_user_data(context, &GRAPH_KEY)?.clone(); - match Self::get_user_data_mut(context, &GRAPHS_KEY).ok() { - None => context.put_concrete(GRAPHS_KEY.key(), vec![graph]), - Some(graphs) => graphs.push(graph), - } + match Self::get_user_data_mut(context, &GRAPHS_KEY).ok() { + None => context.put_concrete(GRAPHS_KEY.key(), vec![graph]), + Some(graphs) => graphs.push(graph), + } - Ok(()) - }) - } + Ok(()) + }); - pub(super) fn clear_graphs() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::CLEAR_GRAPHS, &|context, _, _| { - if let Some(graphs) = Self::get_user_data_mut(context, &GRAPHS_KEY).ok() { - graphs.clear(); - } + pipeline_part!(clear_graphs, |context: &mut PipelineContext, _, _| { + if let Ok(graphs) = Self::get_user_data_mut(context, &GRAPHS_KEY) { + graphs.clear(); + } - Ok(()) - }) - } + Ok(()) + }); - pub(super) fn terminate_if_empty_log() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::TERMINATE_IF_EMPTY_LOG, &|context, _, _| { - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - if log.traces().iter().map(|t| t.borrow().events().len()).sum::() == 0 { - return Err(PipelinePartExecutionError::new_raw("Empty log".to_string())); - } + pipeline_part!(terminate_if_empty_log, |context: &mut PipelineContext, _, _| { + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + if log.traces().iter().map(|t| t.borrow().events().len()).sum::() == 0 { + return Err(PipelinePartExecutionError::new_raw("Empty log".to_string())); + } - Ok(()) - }) - } + Ok(()) + }); } diff --git a/Ficus/src/rust/ficus/src/pipelines/xes_parts.rs b/Ficus/src/rust/ficus/src/pipelines/xes_parts.rs index c2fc34342..1faf34bfb 100644 --- a/Ficus/src/rust/ficus/src/pipelines/xes_parts.rs +++ b/Ficus/src/rust/ficus/src/pipelines/xes_parts.rs @@ -5,7 +5,7 @@ use super::{ use crate::{ event_log::{ bxes::{ - bxes_to_xes_converter::{read_bxes_into_xes_log, read_bxes_into_xes_log_from_bytes, BxesToXesConversionResult}, + bxes_to_xes_converter::{BxesToXesConversionResult, read_bxes_into_xes_log, read_bxes_into_xes_log_from_bytes}, xes_to_bxes_converter::{write_event_log_to_bxes, write_event_log_to_bxes_bytes}, }, xes::{ @@ -14,149 +14,126 @@ use crate::{ writer::xes_event_log_writer::{write_xes_log, write_xes_log_to_bytes}, }, }, + pipeline_part, pipelines::{ context::PipelineContext, - keys::context_keys::{BYTES_KEY, EVENT_LOG_KEY, PATHS_KEY, PATH_KEY, SYSTEM_METADATA_KEY}, + keys::context_keys::{BYTES_KEY, EVENT_LOG_KEY, PATH_KEY, PATHS_KEY, SYSTEM_METADATA_KEY}, pipeline_parts::PipelineParts, }, - utils::user_data::user_data::UserData, + utils::user_data::user_data::{UserData, UserDataImpl}, }; impl PipelineParts { - pub(super) fn write_log_to_xes() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::WRITE_LOG_TO_XES, &|context, _, config| { - let path = Self::get_user_data(config, &PATH_KEY)?; - match write_xes_log(&context.concrete(EVENT_LOG_KEY.key()).unwrap(), path) { - Ok(()) => Ok(()), - Err(err) => Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(err.to_string()))), + pipeline_part!(write_log_to_xes, |context: &mut PipelineContext, _, config: &UserDataImpl| { + let path = Self::get_user_data(config, &PATH_KEY)?; + match write_xes_log(context.concrete(EVENT_LOG_KEY.key()).unwrap(), path) { + Ok(()) => Ok(()), + Err(err) => Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(err.to_string()))), + } + }); + + pipeline_part!(read_log_from_xes, |context: &mut PipelineContext, _, _| { + let path = Self::get_user_data(context, &PATH_KEY)?; + + let log = read_event_log(path); + if log.is_none() { + let message = format!("Failed to read event log from {}", path.as_str()); + return Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(message))); + } + + context.put_concrete(EVENT_LOG_KEY.key(), log.unwrap()); + Ok(()) + }); + + pipeline_part!(read_log_from_bxes, |context: &mut PipelineContext, _, _| { + let path = Self::get_user_data(context, &PATH_KEY)?; + + match read_bxes_into_xes_log(path) { + Ok(result) => { + Self::put_read_result_to_context(context, result); + Ok(()) } - }) - } - - pub(super) fn read_log_from_xes() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::READ_LOG_FROM_XES, &|context, _, _| { - let path = Self::get_user_data(context, &PATH_KEY)?; - - let log = read_event_log(path); - if log.is_none() { - let message = format!("Failed to read event log from {}", path.as_str()); - return Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(message))); - } - - context.put_concrete(EVENT_LOG_KEY.key(), log.unwrap()); - Ok(()) - }) - } - - pub(super) fn read_log_from_bxes() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::READ_LOG_FROM_BXES, &|context, _, _| { - let path = Self::get_user_data(context, &PATH_KEY)?; - - match read_bxes_into_xes_log(path) { - Ok(result) => { - Self::put_read_result_to_context(context, result); - Ok(()) - } - Err(err) => { - let message = format!("Failed to read event log from {}, error: {}", path.as_str(), err.to_string()); - Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(message))) - } + Err(err) => { + let message = format!("Failed to read event log from {}, error: {}", path.as_str(), err); + Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(message))) } - }) - } + } + }); fn put_read_result_to_context(context: &mut PipelineContext, result: BxesToXesConversionResult) { context.put_concrete(EVENT_LOG_KEY.key(), result.xes_log); context.put_concrete(SYSTEM_METADATA_KEY.key(), result.system_metadata); } - pub(super) fn write_log_to_bxes() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::WRITE_LOG_TO_BXES, &|context, _, config| { - let path = Self::get_user_data(config, &PATH_KEY)?; - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - let system_metadata = match Self::get_user_data(context, &SYSTEM_METADATA_KEY) { - Ok(metadata) => Some(metadata), - Err(_) => None, - }; - - match write_event_log_to_bxes(log, system_metadata, path) { - Ok(_) => Ok(()), - Err(err) => Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(err.to_string()))), + pipeline_part!(write_log_to_bxes, |context: &mut PipelineContext, _, config: &UserDataImpl| { + let path = Self::get_user_data(config, &PATH_KEY)?; + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + let system_metadata = Self::get_user_data(context, &SYSTEM_METADATA_KEY).ok(); + + match write_event_log_to_bxes(log, system_metadata, path) { + Ok(_) => Ok(()), + Err(err) => Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(err.to_string()))), + } + }); + + pipeline_part!(read_xes_log_from_bytes, |context: &mut PipelineContext, _, _| { + let bytes = Self::get_user_data(context, &BYTES_KEY)?; + match read_event_log_from_bytes(bytes) { + Some(log) => { + context.put_concrete(EVENT_LOG_KEY.key(), log); + Ok(()) } - }) - } - - pub(super) fn read_xes_from_bytes() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::READ_XES_LOG_FROM_BYTES, &|context, _, _| { - let bytes = Self::get_user_data(context, &BYTES_KEY)?; - match read_event_log_from_bytes(bytes) { - Some(log) => { - context.put_concrete(EVENT_LOG_KEY.key(), log); - Ok(()) - } - None => { - let message = "Failed to read event log from bytes array".to_string(); - return Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(message))); - } + None => { + let message = "Failed to read event log from bytes array".to_string(); + Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(message))) } - }) - } - - pub(super) fn read_bxes_from_bytes() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::READ_BXES_LOG_FROM_BYTES, &|context, _, _| { - let bytes = Self::get_user_data(context, &BYTES_KEY)?; - match read_bxes_into_xes_log_from_bytes(bytes) { - Ok(read_result) => { - Self::put_read_result_to_context(context, read_result); - Ok(()) - } - Err(err) => { - let message = format!("Failed to read event log from bytes: {}", err.to_string()); - Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(message))) - } + } + }); + + pipeline_part!(read_bxes_log_from_bytes, |context: &mut PipelineContext, _, _| { + let bytes = Self::get_user_data(context, &BYTES_KEY)?; + match read_bxes_into_xes_log_from_bytes(bytes) { + Ok(read_result) => { + Self::put_read_result_to_context(context, read_result); + Ok(()) } - }) - } - - pub(super) fn write_bxes_to_bytes() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::WRITE_BXES_LOG_TO_BYTES, &|context, _, _| { - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - let system_metadata = match Self::get_user_data(context, &SYSTEM_METADATA_KEY) { - Ok(metadata) => Some(metadata), - Err(_) => None, - }; - - match write_event_log_to_bxes_bytes(log, system_metadata) { - Ok(bytes) => { - context.put_concrete::>(BYTES_KEY.key(), bytes); - Ok(()) - } - Err(err) => Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(err.to_string()))), + Err(err) => { + let message = format!("Failed to read event log from bytes: {}", err); + Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(message))) } - }) - } + } + }); - pub(super) fn write_xes_to_bytes() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::WRITE_XES_LOG_TO_BYTES, &|context, _, _| { - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - match write_xes_log_to_bytes(log) { - Ok(bytes) => { - context.put_concrete::>(&BYTES_KEY.key(), bytes); - Ok(()) - } - Err(err) => Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(err.to_string()))), + pipeline_part!(write_bxes_log_to_bytes, |context: &mut PipelineContext, _, _| { + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + let system_metadata = Self::get_user_data(context, &SYSTEM_METADATA_KEY).ok(); + + match write_event_log_to_bxes_bytes(log, system_metadata) { + Ok(bytes) => { + context.put_concrete::>(BYTES_KEY.key(), bytes); + Ok(()) } - }) - } + Err(err) => Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(err.to_string()))), + } + }); + + pipeline_part!(write_xes_log_to_bytes, |context: &mut PipelineContext, _, _| { + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + match write_xes_log_to_bytes(log) { + Ok(bytes) => { + context.put_concrete::>(BYTES_KEY.key(), bytes); + Ok(()) + } + Err(err) => Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(err.to_string()))), + } + }); - pub(super) fn merge_xes_logs_from_paths() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::MERGE_XES_LOGS_FROM_PATHS, &|context, _, _| { - let paths = Self::get_user_data(context, &PATHS_KEY)?; - let log = merge_xes_logs(paths); + pipeline_part!(merge_xes_logs_from_paths, |context: &mut PipelineContext, _, _| { + let paths = Self::get_user_data(context, &PATHS_KEY)?; + let log = merge_xes_logs(paths); - context.put_concrete(EVENT_LOG_KEY.key(), log); + context.put_concrete(EVENT_LOG_KEY.key(), log); - Ok(()) - }) - } + Ok(()) + }); } diff --git a/Ficus/src/rust/ficus/src/utils/colors.rs b/Ficus/src/rust/ficus/src/utils/colors.rs index ead87d9f1..5709e7c20 100644 --- a/Ficus/src/rust/ficus/src/utils/colors.rs +++ b/Ficus/src/rust/ficus/src/utils/colors.rs @@ -67,7 +67,7 @@ impl ColorsHolder { pub fn get_or_create(&mut self, name: &str) -> Color { if let Some(existing_color) = self.names_to_colors.get(name) { - existing_color.clone() + *existing_color } else { let new_color = Color::random(Some(&self.used_colors)); self.used_colors.insert(new_color); diff --git a/Ficus/src/rust/ficus/src/utils/display_name.rs b/Ficus/src/rust/ficus/src/utils/display_name.rs index 5244e1496..b02081f59 100644 --- a/Ficus/src/rust/ficus/src/utils/display_name.rs +++ b/Ficus/src/rust/ficus/src/utils/display_name.rs @@ -8,7 +8,7 @@ use crate::{ }; use lazy_static::lazy_static; -const DISPLAY_NAME: &'static str = "DISPLAY_NAME"; +const DISPLAY_NAME: &str = "DISPLAY_NAME"; context_key! { DISPLAY_NAME, String } pub fn get_display_name(event: &XesEventImpl) -> HeapedOrOwned { diff --git a/Ficus/src/rust/ficus/src/utils/distance/distance.rs b/Ficus/src/rust/ficus/src/utils/distance/distance.rs index 3a93a9593..bfab9002f 100644 --- a/Ficus/src/rust/ficus/src/utils/distance/distance.rs +++ b/Ficus/src/rust/ficus/src/utils/distance/distance.rs @@ -103,8 +103,8 @@ pub struct LevenshteinDistance; impl Distance for LevenshteinDistance { fn distance(&self, a: ArrayView, b: ArrayView) -> f64 { - let a_vec = a.iter().map(|x| *x).collect::>(); - let b_vec = b.iter().map(|x| *x).collect::>(); + let a_vec = a.iter().copied().collect::>(); + let b_vec = b.iter().copied().collect::>(); let a_len = Self::get_levenshtein_matrix_dimension_length(&a_vec); let b_len = Self::get_levenshtein_matrix_dimension_length(&b_vec); @@ -149,8 +149,8 @@ pub struct LengthDistance; impl Distance for LengthDistance { fn distance(&self, a: ArrayView, b: ArrayView) -> f64 { - let a_len = find_first_zero_index(&a.into_iter().map(|x| *x).collect()); - let b_len = find_first_zero_index(&b.into_iter().map(|x| *x).collect()); + let a_len = find_first_zero_index(&a.into_iter().copied().collect()); + let b_len = find_first_zero_index(&b.into_iter().copied().collect()); (a_len.max(b_len) - a_len.min(b_len)) as f64 } @@ -161,8 +161,8 @@ pub struct LCSDistance; impl Distance for LCSDistance { fn distance(&self, a: ArrayView, b: ArrayView) -> f64 { - let a_vec = a.iter().map(|x| *x).collect::>(); - let b_vec = b.iter().map(|x| *x).collect::>(); + let a_vec = a.iter().copied().collect::>(); + let b_vec = b.iter().copied().collect::>(); let a_len = find_first_zero_index(&a_vec) + 1; let b_len = find_first_zero_index(&b_vec) + 1; diff --git a/Ficus/src/rust/ficus/src/utils/graph/graph.rs b/Ficus/src/rust/ficus/src/utils/graph/graph.rs index d6cfd9e2d..1c348c8f0 100644 --- a/Ficus/src/rust/ficus/src/utils/graph/graph.rs +++ b/Ficus/src/rust/ficus/src/utils/graph/graph.rs @@ -41,7 +41,7 @@ impl NodesConnectionData { } pub fn weight(&self) -> f64 { - self.weight.clone() + self.weight } } @@ -53,10 +53,7 @@ pub enum GraphKind { impl GraphKind { pub fn is_dag(&self) -> bool { - match self { - Self::Dag | Self::DagLCS => true, - _ => false, - } + matches!(self, Self::Dag | Self::DagLCS) } } @@ -93,7 +90,7 @@ where Self { connections: HashMap::new(), nodes: HashMap::new(), - user_data: UserDataImpl::new(), + user_data: Default::default(), kind: None, } } @@ -107,17 +104,17 @@ where } pub fn all_nodes(&self) -> Vec<&GraphNode> { - self.nodes.values().into_iter().collect() + self.nodes.values().collect() } pub fn all_nodes_mut(&mut self) -> Vec<&mut GraphNode> { - self.nodes.values_mut().into_iter().collect() + self.nodes.values_mut().collect() } pub fn all_edges(&self) -> Vec<&GraphEdge> { let mut edges = vec![]; - for (_, connections) in &self.connections { - for (_, edge) in connections { + for connections in self.connections.values() { + for edge in connections.values() { edges.push(edge) } } @@ -126,20 +123,20 @@ where } pub fn edge(&self, first_node_id: &u64, second_node_id: &u64) -> Option<&GraphEdge> { - if let Some(connections) = self.connections.get(first_node_id) { - if let Some(edge) = connections.get(second_node_id) { - return Some(edge); - } + if let Some(connections) = self.connections.get(first_node_id) + && let Some(edge) = connections.get(second_node_id) + { + return Some(edge); } None } pub fn edge_mut(&mut self, first_node_id: &u64, second_node_id: &u64) -> Option<&mut GraphEdge> { - if let Some(connections) = self.connections.get_mut(first_node_id) { - if let Some(edge) = connections.get_mut(second_node_id) { - return Some(edge); - } + if let Some(connections) = self.connections.get_mut(first_node_id) + && let Some(edge) = connections.get_mut(second_node_id) + { + return Some(edge); } None @@ -169,21 +166,20 @@ where return; } - if let Some(_) = self.nodes.get(first_node_id) { - if let Some(_) = self.nodes.get(second_node_id) { - let edge = GraphEdge::new( - *first_node_id, - *second_node_id, - connection_data.weight, - connection_data.data, - connection_data.user_data, - ); - if let Some(connections) = self.connections.get_mut(first_node_id) { - connections.insert(second_node_id.to_owned(), edge); - } else { - let new_connections = HashMap::from_iter(vec![(second_node_id.to_owned(), edge)]); - self.connections.insert(first_node_id.to_owned(), new_connections); - } + if self.nodes.contains_key(first_node_id) && self.nodes.contains_key(second_node_id) { + let edge = GraphEdge::new( + *first_node_id, + *second_node_id, + connection_data.weight, + connection_data.data, + connection_data.user_data, + ); + + if let Some(connections) = self.connections.get_mut(first_node_id) { + connections.insert(second_node_id.to_owned(), edge); + } else { + let new_connections = HashMap::from_iter(vec![(second_node_id.to_owned(), edge)]); + self.connections.insert(first_node_id.to_owned(), new_connections); } } } diff --git a/Ficus/src/rust/ficus/src/utils/graph/graph_clusters.rs b/Ficus/src/rust/ficus/src/utils/graph/graph_clusters.rs index 6a914dd59..be49b9b0d 100644 --- a/Ficus/src/rust/ficus/src/utils/graph/graph_clusters.rs +++ b/Ficus/src/rust/ficus/src/utils/graph/graph_clusters.rs @@ -24,12 +24,7 @@ where let new_incoming_edges_merged = self.find_incoming_edges(cluster_nodes, &edge_data_merger); let new_outgoing_edges_merged = self.find_outgoing_edges(cluster_nodes, &edge_data_merger); - self.adjust_transitions_for_cluster( - cluster_nodes, - new_node_id.clone(), - new_incoming_edges_merged, - new_outgoing_edges_merged, - ); + self.adjust_transitions_for_cluster(cluster_nodes, new_node_id, new_incoming_edges_merged, new_outgoing_edges_merged); } fn find_incoming_edges( @@ -40,16 +35,16 @@ where let mut new_incoming_edges = HashMap::new(); for node in self.all_nodes() { let node_id = node.id(); - if !cluster_nodes.contains(&node_id) { + if !cluster_nodes.contains(node_id) { let mut edges = vec![]; - if let Some(connections) = self.connections.get(&node_id) { + if let Some(connections) = self.connections.get(node_id) { for cluster_node in cluster_nodes { if let Some(connection_data) = connections.get(cluster_node) { edges.push(connection_data); } } - if edges.len() > 0 { + if !edges.is_empty() { new_incoming_edges.insert(*node_id, edges); } } @@ -103,7 +98,7 @@ where for new_edge in new_incoming_edges_merged { if let Some(connections) = self.connections.get_mut(&new_edge.0) { let edge = GraphEdge::new(new_edge.0, new_node_id, new_edge.1.weight(), new_edge.1.data, new_edge.1.user_data); - connections.insert(new_node_id.clone(), edge); + connections.insert(new_node_id, edge); } } @@ -119,7 +114,7 @@ where self.connections.remove(cluster_node); } - for key in self.connections.keys().into_iter().map(|c| *c).collect::>() { + for key in self.connections.keys().copied().collect::>() { if let Some(connections) = self.connections.get_mut(&key) { for cluster_node_id in cluster_nodes { connections.remove(cluster_node_id); diff --git a/Ficus/src/rust/ficus/src/utils/graph/graph_conversions.rs b/Ficus/src/rust/ficus/src/utils/graph/graph_conversions.rs index a8ed3e3ac..b1b95c5cc 100644 --- a/Ficus/src/rust/ficus/src/utils/graph/graph_conversions.rs +++ b/Ficus/src/rust/ficus/src/utils/graph/graph_conversions.rs @@ -5,7 +5,6 @@ use crate::utils::{ graph_node::GraphNode, }, references::HeapedOrOwned, - user_data::user_data::UserDataImpl, }; use std::{collections::HashMap, fmt::Display}; @@ -18,7 +17,7 @@ where DefaultGraph { nodes: self.to_default_graph_nodes(), connections: self.to_default_graph_connections(), - user_data: UserDataImpl::new(), + user_data: Default::default(), kind: self.kind().clone(), } } @@ -30,10 +29,7 @@ where *pair.0, GraphNode { id: pair.1.id.to_owned(), - data: match &pair.1.data { - None => None, - Some(data) => Some(HeapedOrOwned::Owned(data.to_string())), - }, + data: pair.1.data.as_ref().map(|data| HeapedOrOwned::Owned(data.to_string())), user_data: pair.1.user_data.clone() }, ) @@ -52,10 +48,7 @@ where pair.1.from_node, pair.1.to_node, pair.1.weight, - match pair.1.data() { - None => None, - Some(data) => Some(HeapedOrOwned::Owned(data.to_string())), - }, + pair.1.data().as_ref().map(|data| HeapedOrOwned::Owned(data.to_string())), Some(pair.1.user_data.clone()) ) ) diff --git a/Ficus/src/rust/ficus/src/utils/graph/graph_edge.rs b/Ficus/src/rust/ficus/src/utils/graph/graph_edge.rs index 6b28f2ac7..31c491acd 100644 --- a/Ficus/src/rust/ficus/src/utils/graph/graph_edge.rs +++ b/Ficus/src/rust/ficus/src/utils/graph/graph_edge.rs @@ -32,7 +32,7 @@ where id: NEXT_ID.fetch_add(1, Ordering::SeqCst), data, weight, - user_data: user_data.unwrap_or(UserDataImpl::new()), + user_data: user_data.unwrap_or_default(), } } } diff --git a/Ficus/src/rust/ficus/src/utils/graph/graph_node.rs b/Ficus/src/rust/ficus/src/utils/graph/graph_node.rs index c02939671..97c30c3a2 100644 --- a/Ficus/src/rust/ficus/src/utils/graph/graph_node.rs +++ b/Ficus/src/rust/ficus/src/utils/graph/graph_node.rs @@ -6,9 +6,9 @@ pub struct GraphNode where TNodeData: ToString, { - pub(crate) id: u64, - pub(crate) data: Option, - pub(crate) user_data: UserDataImpl, + pub id: u64, + pub data: Option, + pub user_data: UserDataImpl, } impl GraphNode @@ -19,7 +19,7 @@ where Self { id: NEXT_ID.fetch_add(1, Ordering::SeqCst), data, - user_data: UserDataImpl::new(), + user_data: Default::default(), } } diff --git a/Ficus/src/rust/ficus/src/utils/graph/graphs_merging.rs b/Ficus/src/rust/ficus/src/utils/graph/graphs_merging.rs index 46d59032d..bf2cac572 100644 --- a/Ficus/src/rust/ficus/src/utils/graph/graphs_merging.rs +++ b/Ficus/src/rust/ficus/src/utils/graph/graphs_merging.rs @@ -15,8 +15,8 @@ pub enum GraphsMergingError { MissingEndNode, } -const START_NODE_ID: &'static str = "START_NODE_ID"; -const END_NODE_ID: &'static str = "END_NODE_ID"; +const START_NODE_ID: &str = "START_NODE_ID"; +const END_NODE_ID: &str = "END_NODE_ID"; context_key! { START_NODE_ID, u64 } context_key! { END_NODE_ID, u64 } diff --git a/Ficus/src/rust/ficus/src/utils/interval_tree/interval_tree.rs b/Ficus/src/rust/ficus/src/utils/interval_tree/interval_tree.rs index cb501fff7..d1d372cc7 100644 --- a/Ficus/src/rust/ficus/src/utils/interval_tree/interval_tree.rs +++ b/Ficus/src/rust/ficus/src/utils/interval_tree/interval_tree.rs @@ -12,8 +12,8 @@ where TElementIterator: Iterator, TData: PartialEq + Eq + Copy, { - nodes: Box>>, - boundaries: Box>, + nodes: Vec>, + boundaries: Vec, range_creator: TRangeCreator, } @@ -33,8 +33,8 @@ where intervals: &Vec>, range_creator: TRangeCreator, ) -> IntervalTree { - let mut nodes: Box>> = Box::new(vec![]); - let mut boundaries = Box::new(vec![]); + let mut nodes: Vec> = vec![]; + let mut boundaries = vec![]; let mut queue: VecDeque<(Option<(usize, ChildOrientation)>, Vec<&Interval>)> = VecDeque::new(); @@ -78,11 +78,11 @@ where } nodes.push(node); - if left_intervals.len() > 0 { + if !left_intervals.is_empty() { queue.push_back((Some((node_index, ChildOrientation::Left)), left_intervals)); } - if right_intervals.len() > 0 { + if !right_intervals.is_empty() { queue.push_back((Some((node_index, ChildOrientation::Right)), right_intervals)); } } @@ -151,23 +151,23 @@ where result.insert(*interval); } - if let Some(left_child) = node.left_child { - if point < node.center { - self.search_internal(left_child, point, result); - } + if let Some(left_child) = node.left_child + && point < node.center + { + self.search_internal(left_child, point, result); } - if let Some(right_child) = node.right_child { - if point > node.center { - self.search_internal(right_child, point, result); - } + if let Some(right_child) = node.right_child + && point > node.center + { + self.search_internal(right_child, point, result); } } } pub fn dump_nodes(&self) -> Vec<(Option, Option, TElement, Vec>)> { let mut nodes = vec![]; - for node in self.nodes.as_ref() { + for node in &self.nodes { nodes.push((node.left_child, node.right_child, node.center, node.intervals.to_vec())); } diff --git a/Ficus/src/rust/ficus/src/utils/lcs.rs b/Ficus/src/rust/ficus/src/utils/lcs.rs index 2e9e4e077..e3abbfbd5 100644 --- a/Ficus/src/rust/ficus/src/utils/lcs.rs +++ b/Ficus/src/rust/ficus/src/utils/lcs.rs @@ -5,8 +5,8 @@ pub fn find_longest_common_subsequence_length(first: &Vec, seco } pub fn build_longest_common_subsequence_matrix( - first: &Vec, - second: &Vec, + first: &[T], + second: &[T], first_len: usize, second_len: usize, ) -> Vec> { @@ -52,8 +52,8 @@ impl<'a, T> LCSSearchResult<'a, T> { } pub fn find_longest_common_subsequence<'a, T: PartialEq + Clone>( - first: &'a Vec, - second: &'a Vec, + first: &'a [T], + second: &'a [T], first_len: usize, second_len: usize, ) -> LCSSearchResult<'a, T> { diff --git a/Ficus/src/rust/ficus/src/utils/mod.rs b/Ficus/src/rust/ficus/src/utils/mod.rs index 5c0777dd3..05fccbd3e 100644 --- a/Ficus/src/rust/ficus/src/utils/mod.rs +++ b/Ficus/src/rust/ficus/src/utils/mod.rs @@ -4,7 +4,6 @@ pub mod dataset; pub mod display_name; pub mod distance; pub mod graph; -pub mod grpc_utils; pub mod hash_map_utils; pub mod hash_utils; pub mod interval_tree; diff --git a/Ficus/src/rust/ficus/src/utils/references.rs b/Ficus/src/rust/ficus/src/utils/references.rs index 7b1f48e74..60263a9e1 100644 --- a/Ficus/src/rust/ficus/src/utils/references.rs +++ b/Ficus/src/rust/ficus/src/utils/references.rs @@ -17,7 +17,7 @@ impl<'a, T> Deref for ReferenceOrOwned<'a, T> { fn deref(&self) -> &Self::Target { match self { ReferenceOrOwned::Ref(reference) => reference, - ReferenceOrOwned::Owned(value) => &value, + ReferenceOrOwned::Owned(value) => value, } } } @@ -62,7 +62,7 @@ impl Deref for HeapedOrOwned { fn deref(&self) -> &Self::Target { match self { HeapedOrOwned::Heaped(ptr) => ptr.as_ref().as_ref(), - HeapedOrOwned::Owned(value) => &value, + HeapedOrOwned::Owned(value) => value, } } } diff --git a/Ficus/src/rust/ficus/src/utils/sets/one_set.rs b/Ficus/src/rust/ficus/src/utils/sets/one_set.rs index 1b9db170c..2f0a44145 100644 --- a/Ficus/src/rust/ficus/src/utils/sets/one_set.rs +++ b/Ficus/src/rust/ficus/src/utils/sets/one_set.rs @@ -43,7 +43,7 @@ where pub fn merge(&self, other: &Self) -> Self { Self { id: ONE_SET_NEXT_ID.fetch_add(1, Ordering::SeqCst), - set: self.set.iter().chain(other.set.iter()).map(|el| el.clone()).collect(), + set: self.set.iter().chain(other.set.iter()).cloned().collect(), } } diff --git a/Ficus/src/rust/ficus/src/utils/sets/two_sets.rs b/Ficus/src/rust/ficus/src/utils/sets/two_sets.rs index 4abd54249..972a0930c 100644 --- a/Ficus/src/rust/ficus/src/utils/sets/two_sets.rs +++ b/Ficus/src/rust/ficus/src/utils/sets/two_sets.rs @@ -1,6 +1,7 @@ use crate::utils::hash_utils::compare_based_on_hashes; use std::{ collections::BTreeSet, + fmt::Display, hash::{Hash, Hasher}, }; @@ -41,8 +42,8 @@ where pub fn merge(&self, other: &TwoSets) -> Self { Self { - first_set: self.first_set.iter().chain(other.first_set.iter()).map(|c| c.clone()).collect(), - second_set: self.second_set.iter().chain(other.second_set.iter()).map(|c| c.clone()).collect(), + first_set: self.first_set.iter().chain(other.first_set.iter()).cloned().collect(), + second_set: self.second_set.iter().chain(other.second_set.iter()).cloned().collect(), } } @@ -103,17 +104,17 @@ where { fn clone(&self) -> Self { Self { - first_set: self.first_set.iter().map(|c| c.clone()).collect(), - second_set: self.second_set.iter().map(|c| c.clone()).collect(), + first_set: self.first_set.iter().cloned().collect(), + second_set: self.second_set.iter().cloned().collect(), } } } -impl ToString for TwoSets +impl Display for TwoSets where T: Hash + Eq + ToString + Ord + Clone, { - fn to_string(&self) -> String { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let mut repr = String::new(); repr.push('('); @@ -124,7 +125,7 @@ where repr.push(','); } - if set.len() > 0 { + if !set.is_empty() { repr.remove(repr.len() - 1); } @@ -138,6 +139,7 @@ where write_set(&self.second_set, &mut repr); repr.push(')'); - repr + + write!(f, "{}", repr) } } diff --git a/Ficus/src/rust/ficus/src/utils/silhouette.rs b/Ficus/src/rust/ficus/src/utils/silhouette.rs index 7fbd8604c..98dc47466 100644 --- a/Ficus/src/rust/ficus/src/utils/silhouette.rs +++ b/Ficus/src/rust/ficus/src/utils/silhouette.rs @@ -64,14 +64,10 @@ pub fn silhouette_score(labels: &Vec, distance_func: impl Fn(usize, usize current_b_x /= other_cluster_indices.len() as f64; - b_x = Some(if b_x.is_none() { - current_b_x - } else { - current_b_x.min(b_x.unwrap()) - }) + b_x = Some(if let Some(b_x) = b_x { current_b_x.min(b_x) } else { current_b_x }) } - let b_x = b_x.unwrap_or_else(|| 0.); + let b_x = b_x.unwrap_or(0.); score += (b_x - a_x) / a_x.max(b_x); } } diff --git a/Ficus/src/rust/ficus/src/utils/stream_queue.rs b/Ficus/src/rust/ficus/src/utils/stream_queue.rs index 97d5d4846..2b0be07be 100644 --- a/Ficus/src/rust/ficus/src/utils/stream_queue.rs +++ b/Ficus/src/rust/ficus/src/utils/stream_queue.rs @@ -3,8 +3,8 @@ use std::{ collections::VecDeque, pin::Pin, sync::{ - atomic::{AtomicBool, Ordering}, Arc, Mutex, + atomic::{AtomicBool, Ordering}, }, task::{Context, Poll}, }; @@ -14,14 +14,16 @@ pub struct StreamQueue { queue: VecDeque, } -impl StreamQueue { - pub fn new() -> Self { +impl Default for StreamQueue { + fn default() -> Self { Self { queue: VecDeque::new(), is_active: AtomicBool::new(true), } } +} +impl StreamQueue { pub fn is_active(&self) -> bool { self.is_active.load(Ordering::SeqCst) } @@ -43,20 +45,24 @@ impl Stream for AsyncStreamQueue { if !queue.is_active.load(Ordering::SeqCst) { Poll::Ready(None) + } else if let Some(value) = queue.queue.pop_front() { + Poll::Ready(Some(value)) } else { - if let Some(value) = queue.queue.pop_front() { - Poll::Ready(Some(value)) - } else { - Poll::Pending - } + Poll::Pending } } } +impl Default for AsyncStreamQueue { + fn default() -> Self { + Self::new() + } +} + impl AsyncStreamQueue { pub fn new() -> Self { Self { - queue: Arc::new(Mutex::new(StreamQueue::new())), + queue: Arc::new(Mutex::new(StreamQueue::default())), } } diff --git a/Ficus/src/rust/ficus/src/utils/suffix_tree/node.rs b/Ficus/src/rust/ficus/src/utils/suffix_tree/node.rs index 2506134e5..2f646ee09 100644 --- a/Ficus/src/rust/ficus/src/utils/suffix_tree/node.rs +++ b/Ficus/src/rust/ficus/src/utils/suffix_tree/node.rs @@ -42,9 +42,6 @@ where } pub fn go(&mut self, element: &Option) -> Option { - match self.children.get(element) { - Some(next) => Some(*next), - None => None, - } + self.children.get(element).copied() } } diff --git a/Ficus/src/rust/ficus/src/utils/suffix_tree/suffix_tree_patterns.rs b/Ficus/src/rust/ficus/src/utils/suffix_tree/suffix_tree_patterns.rs index c38e71d50..1f6ca5af9 100644 --- a/Ficus/src/rust/ficus/src/utils/suffix_tree/suffix_tree_patterns.rs +++ b/Ficus/src/rust/ficus/src/utils/suffix_tree/suffix_tree_patterns.rs @@ -73,7 +73,7 @@ where return; } - for (_, child_node_index) in &node.children { + for child_node_index in node.children.values() { self.dfs_pattern_search(*child_node_index, patterns, pattern_length, suffix_length); } } diff --git a/Ficus/src/rust/ficus/src/utils/suffix_tree/suffix_tree_repeats.rs b/Ficus/src/rust/ficus/src/utils/suffix_tree/suffix_tree_repeats.rs index 9aaf3654b..e859cf81f 100644 --- a/Ficus/src/rust/ficus/src/utils/suffix_tree/suffix_tree_repeats.rs +++ b/Ficus/src/rust/ficus/src/utils/suffix_tree/suffix_tree_repeats.rs @@ -58,7 +58,7 @@ where fn create_from_bottom_to_top_nodes_queue(&self) -> VecDeque<(usize, usize)> { let nodes = self.nodes.borrow(); - let start_node = nodes.get(0).unwrap(); + let start_node = nodes.first().unwrap(); let mut queue = VecDeque::from_iter([(0, start_node.edge_len())]); let mut queue_index = 0; @@ -70,7 +70,7 @@ where let (node_index, suffix_length) = queue.get(i).cloned().unwrap(); let node = nodes.get(node_index).unwrap(); - for (_, child_index) in &node.children { + for child_index in node.children.values() { let child_node = nodes.get(*child_index).unwrap(); let child_suffix_length = suffix_length + child_node.edge_len(); queue.push_back((*child_index, child_suffix_length)); @@ -105,15 +105,15 @@ where } let mut child_set = HashMap::new(); - for (_, child_index) in &node.children { - for (element, count) in nodes_to_awc.get(&child_index).unwrap() { + for child_index in node.children.values() { + for (element, count) in nodes_to_awc.get(child_index).unwrap() { increase_in_map_by(&mut child_set, element, *count); } } nodes_to_awc.insert(node_index, child_set); - let children: Vec<&usize> = node.children.values().into_iter().collect(); + let children: Vec<&usize> = node.children.values().collect(); let child_suffix_len = nodes_to_any_suffix_len[children.iter().min().unwrap()]; nodes_to_any_suffix_len.insert(node_index, child_suffix_len); @@ -149,7 +149,7 @@ where RepeatType::SuperMaximalRepeat => { let nodes = &self.nodes.borrow(); - for (_, child_index) in &nodes.get(*node_index).unwrap().children { + for child_index in nodes.get(*node_index).unwrap().children.values() { let child_node = nodes.get(*child_index).unwrap(); if !child_node.is_leaf() { return; @@ -157,7 +157,7 @@ where if child_node.is_leaf() { let element = self.get_element_for_suffix(nodes_to_any_suffix_len[child_index]); - if element != None && nodes_to_awc[node_index][&element] != 1 { + if element.is_some() && nodes_to_awc[node_index][&element] != 1 { return; } } @@ -166,12 +166,12 @@ where RepeatType::NearSuperMaximalRepeat => { let mut witnesses_near_supermaximality = false; let nodes = &self.nodes.borrow(); - for (_, child_index) in &nodes.get(*node_index).unwrap().children { + for child_index in nodes.get(*node_index).unwrap().children.values() { let child_node = nodes.get(*child_index).unwrap(); if child_node.is_leaf() { let element = self.get_element_for_suffix(nodes_to_any_suffix_len[child_index]); - if element != None && nodes_to_awc[node_index][&element] == 1 { + if element.is_some() && nodes_to_awc[node_index][&element] == 1 { witnesses_near_supermaximality = true; } } diff --git a/Ficus/src/rust/ficus/src/utils/suffix_tree/suffix_tree_slice.rs b/Ficus/src/rust/ficus/src/utils/suffix_tree/suffix_tree_slice.rs index 6e2e27e07..3148174c5 100644 --- a/Ficus/src/rust/ficus/src/utils/suffix_tree/suffix_tree_slice.rs +++ b/Ficus/src/rust/ficus/src/utils/suffix_tree/suffix_tree_slice.rs @@ -124,8 +124,7 @@ where { pub fn get_slice_info_for(&self, index: usize) -> Option<(usize, Option)> { let mut next_word_border = 0; - let mut slice_index = 0; - for slice in &self.words { + for (slice_index, slice) in self.words.iter().enumerate() { next_word_border += slice.len(); if index < next_word_border { let index_in_slice = index - (next_word_border - slice.len()); @@ -137,10 +136,9 @@ where } next_word_border += 1; - slice_index += 1; } - return None; + None } pub fn get_slice_part_len(&self, slice_part_index: usize) -> usize { diff --git a/Ficus/src/rust/ficus/src/utils/user_data/keys.rs b/Ficus/src/rust/ficus/src/utils/user_data/keys.rs index 058c3bff7..cd4d3bd9d 100644 --- a/Ficus/src/rust/ficus/src/utils/user_data/keys.rs +++ b/Ficus/src/rust/ficus/src/utils/user_data/keys.rs @@ -32,8 +32,8 @@ impl Clone for DefaultKey { fn clone(&self) -> Self { Self { name: self.name.clone(), - _phantom_data: self._phantom_data.clone(), - _hash: self._hash.clone(), + _phantom_data: self._phantom_data, + _hash: self._hash, } } } diff --git a/Ficus/src/rust/ficus/src/utils/user_data/user_data.rs b/Ficus/src/rust/ficus/src/utils/user_data/user_data.rs index 3a5d18e62..723b10229 100644 --- a/Ficus/src/rust/ficus/src/utils/user_data/user_data.rs +++ b/Ficus/src/rust/ficus/src/utils/user_data/user_data.rs @@ -9,7 +9,7 @@ pub trait UserDataOwner { } pub trait ExecuteWithUserData { - fn execute_with_user_data(&self, func: &mut dyn FnMut(&UserDataImpl) -> ()); + fn execute_with_user_data(&self, func: &mut dyn FnMut(&UserDataImpl)); fn execute_with_user_data_mut(&mut self, func: &mut dyn FnMut(&mut UserDataImpl)); } @@ -21,7 +21,7 @@ struct UserDataValue { key_name: String, } -#[derive(Debug)] +#[derive(Debug, Default)] pub struct UserDataImpl { values_map: Option>, } @@ -46,11 +46,7 @@ pub trait UserData { impl UserData for UserDataImpl { fn len(&self) -> usize { - if let Some(map) = self.values_map.as_ref() { - map.len() - } else { - 0 - } + if let Some(map) = self.values_map.as_ref() { map.len() } else { 0 } } fn put_concrete(&mut self, key: &DefaultKey, value: T) { @@ -71,9 +67,7 @@ impl UserData for UserDataImpl { } fn any(&self, key: &dyn Key) -> Option<&dyn Any> { - if self.values_map.is_none() { - return None; - } + self.values_map.as_ref()?; let values_map = self.values_map.as_ref().unwrap(); if let Some(value) = values_map.get(&key.id()) { @@ -100,28 +94,20 @@ impl UserData for UserDataImpl { } fn items(&self) -> Option, &dyn Any)>> { - if let Some(map) = self.values_map.as_ref() { - Some( - map - .iter() - .map(|(k, v)| { - let key = Box::new(DefaultKey::<()>::existing(*k, v.key_name.to_owned())); - - unsafe { (key as Box, v.value().as_ref().try_borrow_unguarded().ok().unwrap()) } - }) - .collect(), - ) - } else { - None - } + self.values_map.as_ref().map(|map| { + map + .iter() + .map(|(k, v)| { + let key = Box::new(DefaultKey::<()>::existing(*k, v.key_name.to_owned())); + + unsafe { (key as Box, v.value().as_ref().try_borrow_unguarded().ok().unwrap()) } + }) + .collect() + }) } } impl UserDataImpl { - pub fn new() -> Self { - Self { values_map: None } - } - fn initialize_values_map(&mut self) { if self.values_map.is_some() { return; @@ -146,9 +132,7 @@ impl UserDataImpl { } pub fn get_mut(&self, key: &impl Key) -> Option<&mut T> { - if self.values_map.is_none() { - return None; - } + self.values_map.as_ref()?; let values_map = self.values_map.as_ref().unwrap(); if let Some(value) = values_map.get(&key.id()) { @@ -166,7 +150,7 @@ impl Clone for UserDataImpl { Some(map) => { let mut new_map = HashMap::new(); for (key, value) in map { - new_map.insert(key.clone(), value.clone()); + new_map.insert(*key, value.clone()); } Self { values_map: Some(new_map) } @@ -180,6 +164,12 @@ pub struct UserDataHolder { user_data: Option, } +impl Default for UserDataHolder { + fn default() -> Self { + Self::new() + } +} + impl UserDataHolder { pub fn new() -> Self { Self { user_data: None } @@ -187,7 +177,7 @@ impl UserDataHolder { pub fn get_mut(&mut self) -> &mut UserDataImpl { if self.user_data.is_none() { - self.user_data = Some(UserDataImpl::new()); + self.user_data = Some(Default::default()); } self.user_data.as_mut().unwrap() diff --git a/Ficus/src/rust/ficus/src/utils/xml_utils.rs b/Ficus/src/rust/ficus/src/utils/xml_utils.rs index c32d99805..e32f99feb 100644 --- a/Ficus/src/rust/ficus/src/utils/xml_utils.rs +++ b/Ficus/src/rust/ficus/src/utils/xml_utils.rs @@ -7,8 +7,8 @@ use std::{ }; use quick_xml::{ - events::{BytesEnd, BytesStart}, Writer, + events::{BytesEnd, BytesStart}, }; pub enum XmlWriteError { diff --git a/Ficus/src/rust/ficus/tests/analysis/patterns/activities_instances_tests.rs b/Ficus/src/rust/ficus/tests/analysis/patterns/activities_instances_tests.rs index fc1484ba7..8efbc13cd 100644 --- a/Ficus/src/rust/ficus/tests/analysis/patterns/activities_instances_tests.rs +++ b/Ficus/src/rust/ficus/tests/analysis/patterns/activities_instances_tests.rs @@ -9,11 +9,11 @@ use ficus::{ }, features::analysis::patterns::{ activity_instances::{ - create_activity_name, ActivityInTraceFilterKind, ActivityInTraceInfo, ActivityNarrowingKind, UndefActivityHandlingStrategy, - UNDEF_ACTIVITY_NAME, + ActivityInTraceFilterKind, ActivityInTraceInfo, ActivityNarrowingKind, UNDEF_ACTIVITY_NAME, UndefActivityHandlingStrategy, + create_activity_name, }, contexts::{ActivitiesDiscoveryContext, ActivitiesInstancesDiscoveryContext, PatternsDiscoveryContext, PatternsDiscoveryStrategy}, - entry_points::{create_logs_for_activities, discover_activities_and_create_new_log, discover_activities_instances, PatternsKind}, + entry_points::{PatternsKind, create_logs_for_activities, discover_activities_and_create_new_log, discover_activities_instances}, }, vecs, }; diff --git a/Ficus/src/rust/ficus/tests/analysis/patterns/patterns_tests.rs b/Ficus/src/rust/ficus/tests/analysis/patterns/patterns_tests.rs index b12c57ea4..7c09cab57 100644 --- a/Ficus/src/rust/ficus/tests/analysis/patterns/patterns_tests.rs +++ b/Ficus/src/rust/ficus/tests/analysis/patterns/patterns_tests.rs @@ -17,7 +17,7 @@ use ficus::{ contexts::PatternsDiscoveryStrategy, repeats::{find_maximal_repeats, find_near_super_maximal_repeats, find_super_maximal_repeats}, tandem_arrays::{ - find_maximal_tandem_arrays_with_length, find_primitive_tandem_arrays_with_length, SubArrayInTraceInfo, TandemArrayInfo, + SubArrayInTraceInfo, TandemArrayInfo, find_maximal_tandem_arrays_with_length, find_primitive_tandem_arrays_with_length, }, }, }; @@ -41,7 +41,7 @@ fn execute_test_with_positions( TValue: PartialEq + Debug, { let log = log_creator(); - let hashes = log.to_hashes_event_log(&NameEventHasher::new()); + let hashes = log.to_hashes_event_log(&NameEventHasher::default()); let patterns = patterns_finder(&hashes); assert_eq!(patterns.as_slice(), expected); @@ -65,7 +65,7 @@ fn execute_test_with_string_dump( TPatternsFinder: Fn(&Vec>) -> Vec>, { let log = log_creator(); - let hashes = log.to_hashes_event_log(&NameEventHasher::new()); + let hashes = log.to_hashes_event_log(&NameEventHasher::default()); let patterns = patterns_finder(&hashes); let mut dump = dump_repeats_to_string(&patterns, &log); @@ -88,7 +88,7 @@ fn get_first_trace_tuples(tandem_arrays: &Vec>) -> Vec<(usi #[test] fn test_no_tandem_arrays() { let log = create_no_tandem_array_log(); - let hashes = log.to_hashes_event_log(&NameEventHasher::new()); + let hashes = log.to_hashes_event_log(&NameEventHasher::default()); let tandem_arrays = find_maximal_tandem_arrays_with_length(&hashes, 10, false); assert_eq!(get_first_trace_tuples(&tandem_arrays), []); @@ -133,7 +133,7 @@ fn test_tandem_arrays2() { #[test] fn test_tandem_arrays2_string() { let log = create_log_for_max_repeats2(); - let hashes = log.to_hashes_event_log(&NameEventHasher::new()); + let hashes = log.to_hashes_event_log(&NameEventHasher::default()); let tandem_arrays = find_primitive_tandem_arrays_with_length(&hashes, 10, false); diff --git a/Ficus/src/rust/ficus/tests/analysis/patterns/repeat_sets_tests.rs b/Ficus/src/rust/ficus/tests/analysis/patterns/repeat_sets_tests.rs index f1cc364d0..07435538b 100644 --- a/Ficus/src/rust/ficus/tests/analysis/patterns/repeat_sets_tests.rs +++ b/Ficus/src/rust/ficus/tests/analysis/patterns/repeat_sets_tests.rs @@ -3,9 +3,9 @@ use std::{cell::RefCell, ops::Deref, rc::Rc}; use ficus::{ event_log::core::event::event_hasher::default_class_extractor, features::analysis::patterns::{ - activity_instances::{create_activity_name, ActivityInTraceFilterKind, ActivityNarrowingKind}, + activity_instances::{ActivityInTraceFilterKind, ActivityNarrowingKind, create_activity_name}, contexts::{ActivitiesDiscoveryContext, PatternsDiscoveryContext, PatternsDiscoveryStrategy}, - entry_points::{build_repeat_set_tree, find_repeats, PatternsKind}, + entry_points::{PatternsKind, build_repeat_set_tree, find_repeats}, repeat_sets::{ActivityNode, SubArrayWithTraceIndex}, }, }; diff --git a/Ficus/src/rust/ficus/tests/annotations/annotation_tests.rs b/Ficus/src/rust/ficus/tests/annotations/annotation_tests.rs index 213f05226..dfc5c0541 100644 --- a/Ficus/src/rust/ficus/tests/annotations/annotation_tests.rs +++ b/Ficus/src/rust/ficus/tests/annotations/annotation_tests.rs @@ -10,8 +10,8 @@ use ficus::{ alpha::{alpha::discover_petri_net_alpha, providers::alpha_provider::DefaultAlphaRelationsProvider}, petri_net::{ annotations::{ - annotate_with_counts, annotate_with_frequencies, annotate_with_time_performance, annotate_with_trace_frequency, - TimeAnnotationKind, + TimeAnnotationKind, annotate_with_counts, annotate_with_frequencies, annotate_with_time_performance, + annotate_with_trace_frequency, }, petri_net::DefaultPetriNet, }, diff --git a/Ficus/src/rust/ficus/tests/clustering/silhouette_score_tests.rs b/Ficus/src/rust/ficus/tests/clustering/silhouette_score_tests.rs index 73a6fb0ae..615232b9d 100644 --- a/Ficus/src/rust/ficus/tests/clustering/silhouette_score_tests.rs +++ b/Ficus/src/rust/ficus/tests/clustering/silhouette_score_tests.rs @@ -3,12 +3,12 @@ use ficus::{ features::clustering::traces::common::calculate_distance, utils::{ distance::distance::{DistanceWrapper, FicusDistance}, - silhouette::{silhouette_score, SilhouetteScoreError}, + silhouette::{SilhouetteScoreError, silhouette_score}, }, }; -use linfa::{metrics::SilhouetteScore, prelude::Transformer, DatasetBase}; +use linfa::{DatasetBase, metrics::SilhouetteScore, prelude::Transformer}; use linfa_clustering::Dbscan; -use linfa_nn::{distance::L2Dist, CommonNearestNeighbour::KdTree}; +use linfa_nn::{CommonNearestNeighbour::KdTree, distance::L2Dist}; use ndarray::{Array1, Array2}; #[test] diff --git a/Ficus/src/rust/ficus/tests/discovery/root_sequence_discovery.rs b/Ficus/src/rust/ficus/tests/discovery/ecfg_discovery.rs similarity index 82% rename from Ficus/src/rust/ficus/tests/discovery/root_sequence_discovery.rs rename to Ficus/src/rust/ficus/tests/discovery/ecfg_discovery.rs index 34d0c6ff0..b306eb04c 100644 --- a/Ficus/src/rust/ficus/tests/discovery/root_sequence_discovery.rs +++ b/Ficus/src/rust/ficus/tests/discovery/ecfg_discovery.rs @@ -1,7 +1,7 @@ use ficus::{ - features::discovery::root_sequence::{ + features::discovery::ecfg::{ context::DiscoveryContext, - discovery::discover_root_sequence_graph, + discovery::discover_ecfg, models::{EventWithUniqueId, RootSequenceKind}, root_sequence::discover_root_sequence, }, @@ -11,8 +11,8 @@ use ficus::{ use termgraph::{Config, DirectedGraph, ValueFormatter}; #[test] -pub fn test_root_sequence_graph_1() { - execute_root_sequence_discovery_test( +pub fn test_ecfg_1() { + execute_ecfg_discovery_test( vec![vecs!["A", "B", "C", "D", "E"], vecs!["A", "B", "D", "E"]], vecs!["START", "A", "B", "C", "D", "E", "END"], vec![ @@ -28,8 +28,8 @@ pub fn test_root_sequence_graph_1() { } #[test] -pub fn test_root_sequence_graph_2() { - execute_root_sequence_discovery_test( +pub fn test_ecfg_2() { + execute_ecfg_discovery_test( vec![vecs!["A", "B", "C", "D", "E"], vecs!["A", "X", "Y", "E"]], vecs!["START", "A", "B", "C", "D", "E", "END"], vec![ @@ -47,8 +47,8 @@ pub fn test_root_sequence_graph_2() { } #[test] -pub fn test_root_sequence_graph_3() { - execute_root_sequence_discovery_test( +pub fn test_ecfg_3() { + execute_ecfg_discovery_test( vec![vecs!["A"], vecs!["B"], vecs!["C"], vecs!["D"], vecs!["E"]], vecs!["START", "END"], vec![ @@ -67,18 +67,18 @@ pub fn test_root_sequence_graph_3() { } #[test] -pub fn test_root_sequence_graph_4() { - execute_root_sequence_discovery_test(vec![], vec![], vec![]) +pub fn test_ecfg_4() { + execute_ecfg_discovery_test(vec![], vec![], vec![]) } #[test] -pub fn test_root_sequence_graph_5() { - execute_root_sequence_discovery_test(vec![vecs![]], vecs!["START", "END"], vec!["[START]--[END]"]) +pub fn test_ecfg_5() { + execute_ecfg_discovery_test(vec![vecs![]], vecs!["START", "END"], vec!["[START]--[END]"]) } #[test] -pub fn test_root_sequence_graph_6() { - execute_root_sequence_discovery_test( +pub fn test_ecfg_6() { + execute_ecfg_discovery_test( vec![ vecs!["A", "X", "B", "Y", "C", "Z", "D", "W", "E"], vecs!["X", "A", "Y", "B", "Z", "C", "W", "D"], @@ -109,8 +109,8 @@ pub fn test_root_sequence_graph_6() { } #[test] -pub fn test_root_sequence_graph_7() { - execute_root_sequence_discovery_test( +pub fn test_ecfg_7() { + execute_ecfg_discovery_test( vec![ vecs!["X", "A", "Y", "B", "Z", "C", "W", "D", "Z", "E"], vecs!["A", "B", "C", "D", "E"], @@ -138,8 +138,8 @@ pub fn test_root_sequence_graph_7() { } #[test] -pub fn test_root_sequence_graph_8() { - execute_root_sequence_discovery_test( +pub fn test_ecfg_8() { + execute_ecfg_discovery_test( vec![ vecs!["A", "B", "C", "D", "E"], vecs!["A", "X", "B", "C", "D", "E"], @@ -163,8 +163,8 @@ pub fn test_root_sequence_graph_8() { } #[test] -pub fn test_root_sequence_graph_9() { - execute_root_sequence_discovery_test( +pub fn test_ecfg_9() { + execute_ecfg_discovery_test( vec![ vecs!["A", "B", "C", "D", "E"], vecs!["A", "X", "Y", "Z", "W", "B", "C", "D", "E"], @@ -193,8 +193,8 @@ pub fn test_root_sequence_graph_9() { } #[test] -pub fn test_root_sequence_graph_10() { - execute_root_sequence_discovery_test( +pub fn test_ecfg_10() { + execute_ecfg_discovery_test( vec![ vecs!["A", "B", "C", "D", "E"], vecs!["A", "X", "Y", "Z", "W", "B", "C", "D", "E"], @@ -225,21 +225,29 @@ pub fn test_root_sequence_graph_10() { } #[test] -pub fn test_root_sequence_graph_11() { - execute_root_sequence_discovery_test( +pub fn test_ecfg_11() { + execute_ecfg_discovery_test( vec![ vecs!["5", "6", "7", "8", "0"], vecs!["13", "1", "0", "9", "14"], - vecs!["13", "Loop[6]", "Loop[7]", "8", "Loop[15]", "18", "19", "20", "21", "17", "22", "Loop[23]", "Loop[24]", "8", "Loop[16]", "14"], + vecs![ + "13", "Loop[6]", "Loop[7]", "8", "Loop[15]", "18", "19", "20", "21", "17", "22", "Loop[23]", "Loop[24]", "8", "Loop[16]", "14" + ], vecs!["13", "Loop[6]", "Loop[7]", "9", "Loop[26]", "23", "Loop[24]", "27", "8", "14"], - vecs!["5", "7", "0", "28", "26", "Loop[23]", "Loop[24]", "8", "16", "0", "28", "20", "21", "10"], + vecs![ + "5", "7", "0", "28", "26", "Loop[23]", "Loop[24]", "8", "16", "0", "28", "20", "21", "10" + ], vecs!["5", "Loop[6]", "29", "7", "8", "Loop[17]", "11", "28", "8", "Loop[16]", "10"], - vecs!["5", "Loop[7]", "8", "0", "20", "21", "18", "19", "20", "21", "Loop[17]", "22", "Loop[26]", "8", "Loop[16]", "10"], + vecs![ + "5", "Loop[7]", "8", "0", "20", "21", "18", "19", "20", "21", "Loop[17]", "22", "Loop[26]", "8", "Loop[16]", "10" + ], vecs![ "13", "Loop[6]", "29", "Loop[7]", "8", "15", "30", "Loop[26]", "Loop[23]", "Loop[24]", "Loop[27]", "8", "Loop[0]", "28", "20", "21", "16", "14" ], - vecs!["5", "7", "31", "15", "18", "19", "20", "21", "Loop[17]", "11", "28", "Loop[26]", "23", "8", "Loop[16]", "10"], + vecs![ + "5", "7", "31", "15", "18", "19", "20", "21", "Loop[17]", "11", "28", "Loop[26]", "23", "8", "Loop[16]", "10" + ], ], vecs![ "START", "5", "Loop[7]", "8", "0", "20", "21", "18", "19", "20", "21", "Loop[17]", "22", "Loop[26]", "8", "Loop[16]", "10", "END" @@ -335,7 +343,7 @@ pub fn test_root_sequence_graph_11() { ) } -fn execute_root_sequence_discovery_test(mut traces: Vec>, gold_root_sequence: Vec, gold_graph_edges: Vec<&str>) { +fn execute_ecfg_discovery_test(mut traces: Vec>, gold_root_sequence: Vec, gold_graph_edges: Vec<&str>) { const START: &'static str = "START"; const END: &'static str = "END"; @@ -367,10 +375,9 @@ fn execute_root_sequence_discovery_test(mut traces: Vec>, gold_root_ .into_iter() .map(|t| t.into_iter().map(|e| EventWithUniqueId::new(e)).collect()) .collect(); - let graph = discover_root_sequence_graph(&traces, &context, false, None) - .ok() - .unwrap() - .graph_move(); + + let graph = discover_ecfg(&traces, &context, false, None).ok().unwrap().graph_move(); + let test_result = graph.serialize_edges_deterministic(false); let gold = gold_graph_edges.join("\n"); diff --git a/Ficus/src/rust/ficus/tests/discovery/mod.rs b/Ficus/src/rust/ficus/tests/discovery/mod.rs index d7254e308..bcb1b609e 100644 --- a/Ficus/src/rust/ficus/tests/discovery/mod.rs +++ b/Ficus/src/rust/ficus/tests/discovery/mod.rs @@ -1,5 +1,5 @@ pub mod alpha_nfc_plus_plus_tests; pub mod alpha_tests; +pub mod ecfg_discovery; pub mod heuristic_miner_tests; pub mod multithreaded_dfg_tests; -pub mod root_sequence_discovery; diff --git a/Ficus/src/rust/ficus/tests/discovery/multithreaded_dfg_tests.rs b/Ficus/src/rust/ficus/tests/discovery/multithreaded_dfg_tests.rs index d48e64830..066cc672e 100644 --- a/Ficus/src/rust/ficus/tests/discovery/multithreaded_dfg_tests.rs +++ b/Ficus/src/rust/ficus/tests/discovery/multithreaded_dfg_tests.rs @@ -7,7 +7,7 @@ use ficus::{ }, xes::{xes_event::XesEventImpl, xes_event_log::XesEventLogImpl, xes_trace::XesTraceImpl}, }, - features::discovery::multithreaded_dfg::dfg::{discover_multithreaded_dfg, MultithreadedTracePartsCreationStrategy}, + features::discovery::multithreaded_dfg::dfg::{MultithreadedTracePartsCreationStrategy, discover_multithreaded_dfg}, }; use std::{cell::RefCell, rc::Rc}; diff --git a/Ficus/src/rust/ficus/tests/mutations/mutations_tests.rs b/Ficus/src/rust/ficus/tests/mutations/mutations_tests.rs index e7000a8ff..76210c0ae 100644 --- a/Ficus/src/rust/ficus/tests/mutations/mutations_tests.rs +++ b/Ficus/src/rust/ficus/tests/mutations/mutations_tests.rs @@ -9,7 +9,7 @@ use ficus::{ }, features::mutations::{ filtering::{filter_log_by_name, filter_log_by_names}, - mutations::{add_artificial_start_end_activities, rename_events, ARTIFICIAL_END_EVENT_NAME, ARTIFICIAL_START_EVENT_NAME}, + mutations::{ARTIFICIAL_END_EVENT_NAME, ARTIFICIAL_START_EVENT_NAME, add_artificial_start_end_activities, rename_events}, }, }; use std::{cell::RefCell, collections::HashSet, rc::Rc, vec}; diff --git a/Ficus/src/rust/ficus/tests/pipelines/pipeline_keys_tests.rs b/Ficus/src/rust/ficus/tests/pipelines/pipeline_keys_tests.rs index 2e71c51f7..b78d97c22 100644 --- a/Ficus/src/rust/ficus/tests/pipelines/pipeline_keys_tests.rs +++ b/Ficus/src/rust/ficus/tests/pipelines/pipeline_keys_tests.rs @@ -17,9 +17,9 @@ use ficus::{ traces::traces_params::{FeatureCountKind, TracesRepresentationSource}, }, discovery::{ + ecfg::models::RootSequenceKind, ocel::graph_annotation::OcelAnnotationCreationError, petri_net::{annotations::TimeAnnotationKind, petri_net::DefaultPetriNet}, - root_sequence::models::RootSequenceKind, timeline::discovery::LogTimelineDiagram, }, }, diff --git a/Ficus/src/rust/ficus/tests/pipelines/pipeline_parts_tests.rs b/Ficus/src/rust/ficus/tests/pipelines/pipeline_parts_tests.rs index d40c2c432..a1bf2bcc6 100644 --- a/Ficus/src/rust/ficus/tests/pipelines/pipeline_parts_tests.rs +++ b/Ficus/src/rust/ficus/tests/pipelines/pipeline_parts_tests.rs @@ -76,7 +76,7 @@ fn get_test_parts_names() -> Vec { "AbstractTimelineDiagram", "ClusterizeLogTracesKMeansGridSearch", "ClusterizeLogTracesDbscanGridSearch", - "DiscoverRootSequenceGraph", + "DiscoverECFG", "DiscoverLoopsStrict", "DiscoverTracesTimelineDiagram", "PrepareSoftwareEventLog", diff --git a/Ficus/src/rust/ficus/tests/streaming/t1_filterers_test.rs b/Ficus/src/rust/ficus/tests/streaming/t1_filterers_test.rs index 89ba874bc..d6a144928 100644 --- a/Ficus/src/rust/ficus/tests/streaming/t1_filterers_test.rs +++ b/Ficus/src/rust/ficus/tests/streaming/t1_filterers_test.rs @@ -2,7 +2,7 @@ use crate::test_core::simple_events_logs_provider::{annotate_log_with_real_time, use chrono::{Duration, Utc}; use ficus::{ event_log::{core::event_log::EventLog, xes::xes_event_log::XesEventLogImpl}, - grpc::kafka::streaming::t1::{ + features::streaming::t1::{ configs::{EventsTimeoutConfiguration, TracesQueueConfiguration, TracesTimeoutConfiguration}, filterers::{EventsTimeoutFiltererImpl, TracesQueueFiltererImpl, TracesTimeoutFiltererImpl}, }, diff --git a/Ficus/src/rust/ficus/tests/utils/user_data_tests.rs b/Ficus/src/rust/ficus/tests/utils/user_data_tests.rs index 8c9180251..1094069c1 100644 --- a/Ficus/src/rust/ficus/tests/utils/user_data_tests.rs +++ b/Ficus/src/rust/ficus/tests/utils/user_data_tests.rs @@ -8,7 +8,7 @@ use ficus::utils::user_data::{ #[test] fn test_user_data() { let key = DefaultKey::::new("asdasdasda".to_string()); - let mut user_data = UserDataImpl::new(); + let mut user_data = UserDataImpl::default(); let b = 123; user_data.put_concrete(&key, b); @@ -28,7 +28,7 @@ fn test_user_data_two_keys() { let box1 = Rc::clone(&first_value); let box2 = Rc::clone(&second_value); - let mut user_data = UserDataImpl::new(); + let mut user_data = UserDataImpl::default(); user_data.put_any(&first_key, box1); user_data.put_any(&second_key, box2); @@ -45,7 +45,7 @@ fn test_remove_from_user_data() { let key = DefaultKey::::new("1".to_string()); let value = 123usize; - let mut user_data = UserDataImpl::new(); + let mut user_data = UserDataImpl::default(); user_data.put_any(&key, value); diff --git a/Ficus/src/rust/ficus_backend/Cargo.toml b/Ficus/src/rust/ficus_backend/Cargo.toml index 0dae96b41..d7f65e9e1 100644 --- a/Ficus/src/rust/ficus_backend/Cargo.toml +++ b/Ficus/src/rust/ficus_backend/Cargo.toml @@ -5,8 +5,21 @@ edition = "2021" [dependencies] ficus = { path = "../ficus" } -tokio = "1.49.0" tonic = "0.9.2" colog = "1.4.0" log = "0.4.29" +rdkafka = { version = "0.36.2", features = ["cmake-build"] } +bxes_kafka = { path = "../../../../bxes/src/rust/bxes_kafka" } +tokio-stream = "0.1.17" +tokio = { version = "1.49.0", features = ["rt-multi-thread"] } +prost = "0.11.9" +prost-types = "0.11.9" +uuid = { version = "1.19.0", features = ["v4"] } +nameof = "1.3.0" +chrono = "0.4.42" +serde_json = "1.0.148" +futures = "0.3.31" +bxes = { path = "../../../../bxes/src/rust/bxes/" } +[build-dependencies] +tonic-build = "0.9.2" \ No newline at end of file diff --git a/Ficus/src/rust/ficus/build.rs b/Ficus/src/rust/ficus_backend/build.rs similarity index 100% rename from Ficus/src/rust/ficus/build.rs rename to Ficus/src/rust/ficus_backend/build.rs diff --git a/Ficus/src/rust/ficus/src/grpc/backend_service.rs b/Ficus/src/rust/ficus_backend/src/grpc/backend_service.rs similarity index 97% rename from Ficus/src/rust/ficus/src/grpc/backend_service.rs rename to Ficus/src/rust/ficus_backend/src/grpc/backend_service.rs index e99003db0..c873ca495 100644 --- a/Ficus/src/rust/ficus/src/grpc/backend_service.rs +++ b/Ficus/src/rust/ficus_backend/src/grpc/backend_service.rs @@ -12,6 +12,8 @@ use crate::{ context_values_service::ContextValueService, converters::convert_to_grpc_context_value, pipeline_executor::ServicePipelineExecutionContext, }, +}; +use ficus::{ pipelines::{keys::context_keys::find_context_key, pipeline_parts::PipelineParts}, utils::{context_key::DefaultContextKey, user_data::user_data::UserData}, }; @@ -137,11 +139,7 @@ impl GrpcBackendService for FicusService { match self.contexts.lock().as_ref().unwrap().get(&id.guid) { None => Err(Status::not_found("The context values for supplied execution id are not found")), Some(keys_to_cv_ids) => Ok(Response::new(GrpcGetAllContextValuesResult { - context_values: keys_to_cv_ids - .values() - .into_iter() - .map(|id| GrpcGuid { guid: id.to_string() }) - .collect(), + context_values: keys_to_cv_ids.values().map(|id| GrpcGuid { guid: id.to_string() }).collect(), })), } } diff --git a/Ficus/src/rust/ficus/src/grpc/context_values_service.rs b/Ficus/src/rust/ficus_backend/src/grpc/context_values_service.rs similarity index 97% rename from Ficus/src/rust/ficus/src/grpc/context_values_service.rs rename to Ficus/src/rust/ficus_backend/src/grpc/context_values_service.rs index fe151f2c8..bddca145a 100644 --- a/Ficus/src/rust/ficus/src/grpc/context_values_service.rs +++ b/Ficus/src/rust/ficus_backend/src/grpc/context_values_service.rs @@ -64,13 +64,12 @@ impl ContextValueService { let context_values = self.context_values.lock(); let context_values = context_values.as_ref().expect("Must acquire lock"); - match context_values.get(key) { - None => None, - Some(value) => Some(( + context_values.get(key).map(|value| { + ( value.key.as_ref().unwrap().name.clone(), value.value.as_ref().unwrap().encode_to_vec(), - )), - } + ) + }) } } @@ -134,7 +133,7 @@ impl GrpcContextValuesService for GrpcContextValueService { match sender.send(Ok(part)).await { Ok(_) => {} Err(err) => { - log::error!("Failed to send context value part {}, error {}", key, err.to_string()); + log::error!("Failed to send context value part {}, error {}", key, err); break; } } diff --git a/Ficus/src/rust/ficus/src/grpc/converters.rs b/Ficus/src/rust/ficus_backend/src/grpc/converters.rs similarity index 90% rename from Ficus/src/rust/ficus/src/grpc/converters.rs rename to Ficus/src/rust/ficus_backend/src/grpc/converters.rs index 563b0712a..154132a99 100644 --- a/Ficus/src/rust/ficus/src/grpc/converters.rs +++ b/Ficus/src/rust/ficus_backend/src/grpc/converters.rs @@ -1,4 +1,25 @@ -use crate::{ +use crate::ficus_proto::{ + grpc_annotation::Annotation::{CountAnnotation, FrequencyAnnotation, TimeAnnotation}, + grpc_context_value::{ContextValue, ContextValue::Annotation}, + grpc_event_attribute, grpc_graph_edge_additional_data, + grpc_node_additional_data::Data, + grpc_ocel_data, GrpcActivityDurationData, GrpcActivityStartEndData, GrpcAnnotation, GrpcBytes, GrpcColor, GrpcColoredRectangle, + GrpcColorsEventLog, GrpcColorsEventLogMapping, GrpcColorsTrace, GrpcContextValue, GrpcCountAnnotation, GrpcDataset, GrpcDurationKind, + GrpcEdgeExecutionInfo, GrpcEntityCountAnnotation, GrpcEntityFrequencyAnnotation, GrpcEntityTimeAnnotation, GrpcEvent, GrpcEventAttribute, + GrpcEventCoordinates, GrpcEventLogInfo, GrpcEventLogTraceSubArraysContextValue, GrpcFrequenciesAnnotation, GrpcGeneralHistogramData, + GrpcGenericEnhancementBase, GrpcGraph, GrpcGraphEdge, GrpcGraphEdgeAdditionalData, GrpcGraphKind, GrpcGraphNode, GrpcGuid, + GrpcHashesEventLog, GrpcHashesEventLogContextValue, GrpcHashesLogTrace, GrpcHistogramEntry, GrpcLabeledDataset, GrpcLogPoint, + GrpcLogTimelineDiagram, GrpcMatrix, GrpcMatrixRow, GrpcModelElementOcelAnnotation, GrpcMultithreadedFragment, GrpcNamesEventLog, + GrpcNamesEventLogContextValue, GrpcNamesTrace, GrpcNodeAdditionalData, GrpcNodeCorrespondingTraceData, GrpcOcelAllocateMerge, + GrpcOcelConsumeProduce, GrpcOcelData, GrpcOcelModelAnnotation, GrpcOcelObjectTypeData, GrpcOcelObjectTypeState, GrpcOcelProducedObject, + GrpcOcelState, GrpcOcelStateObjectRelation, GrpcPetriNet, GrpcPetriNetArc, GrpcPetriNetMarking, GrpcPetriNetPlace, + GrpcPetriNetSinglePlaceMarking, GrpcPetriNetTransition, GrpcSimpleCounterData, GrpcSimpleEventLog, GrpcSimpleTrace, GrpcSoftwareData, + GrpcSubArrayWithTraceIndex, GrpcSubArraysWithTraceIndexContextValue, GrpcThread, GrpcThreadEvent, GrpcTimePerformanceAnnotation, + GrpcTimeSpan, GrpcTimelineDiagramFragment, GrpcTimelineTraceEventsGroup, GrpcTraceSubArray, GrpcTraceSubArrays, GrpcTraceTimelineDiagram, + GrpcUnderlyingPatternInfo, GrpcUnderlyingPatternKind, +}; +use chrono::{DateTime, Utc}; +use ficus::{ event_log::{ core::{ event::event::{Event, EventPayloadValue}, @@ -20,16 +41,7 @@ use crate::{ }, clustering::{activities::activities_params::ActivityRepresentationSource, traces::traces_params::TracesRepresentationSource}, discovery::{ - ocel::graph_annotation::{NodeObjectsState, OcelAnnotation, OcelObjectRelations}, - petri_net::{ - annotations::TimeAnnotationKind, - arc::Arc, - marking::{Marking, SingleMarking}, - petri_net::DefaultPetriNet, - place::Place, - transition::Transition, - }, - root_sequence::{ + ecfg::{ context_keys::{ EDGE_SOFTWARE_DATA_KEY, EDGE_START_END_ACTIVITIES_TIMES_KEY, EDGE_TRACE_EXECUTION_INFO_KEY, NODE_CORRESPONDING_TRACE_DATA_KEY, NODE_INNER_GRAPH_KEY, NODE_MULTITHREADED_FRAGMENT_LOG_KEY, NODE_SOFTWARE_DATA_KEY, NODE_START_END_ACTIVITIES_TIMES_KEY, @@ -40,6 +52,15 @@ use crate::{ RootSequenceKind, }, }, + ocel::graph_annotation::{NodeObjectsState, OcelAnnotation, OcelObjectRelations}, + petri_net::{ + annotations::TimeAnnotationKind, + arc::Arc, + marking::{Marking, SingleMarking}, + petri_net::DefaultPetriNet, + place::Place, + transition::Transition, + }, timeline::{ discovery::{LogPoint, LogTimelineDiagram, TraceThread}, software_data::models::{ @@ -49,27 +70,6 @@ use crate::{ }, }, }, - ficus_proto::{ - grpc_annotation::Annotation::{CountAnnotation, FrequencyAnnotation, TimeAnnotation}, - grpc_context_value::{ContextValue, ContextValue::Annotation}, - grpc_event_attribute, grpc_graph_edge_additional_data, - grpc_node_additional_data::Data, - grpc_ocel_data, GrpcActivityDurationData, GrpcActivityStartEndData, GrpcAnnotation, GrpcBytes, GrpcColor, GrpcColoredRectangle, - GrpcColorsEventLog, GrpcColorsEventLogMapping, GrpcColorsTrace, GrpcContextValue, GrpcCountAnnotation, GrpcDataset, GrpcDurationKind, - GrpcEdgeExecutionInfo, GrpcEntityCountAnnotation, GrpcEntityFrequencyAnnotation, GrpcEntityTimeAnnotation, GrpcEvent, - GrpcEventAttribute, GrpcEventCoordinates, GrpcEventLogInfo, GrpcEventLogTraceSubArraysContextValue, GrpcFrequenciesAnnotation, - GrpcGeneralHistogramData, GrpcGenericEnhancementBase, GrpcGraph, GrpcGraphEdge, GrpcGraphEdgeAdditionalData, GrpcGraphKind, - GrpcGraphNode, GrpcGuid, GrpcHashesEventLog, GrpcHashesEventLogContextValue, GrpcHashesLogTrace, GrpcHistogramEntry, - GrpcLabeledDataset, GrpcLogPoint, GrpcLogTimelineDiagram, GrpcMatrix, GrpcMatrixRow, GrpcModelElementOcelAnnotation, - GrpcMultithreadedFragment, GrpcNamesEventLog, GrpcNamesEventLogContextValue, GrpcNamesTrace, GrpcNodeAdditionalData, - GrpcNodeCorrespondingTraceData, GrpcOcelAllocateMerge, GrpcOcelConsumeProduce, GrpcOcelData, GrpcOcelModelAnnotation, - GrpcOcelObjectTypeData, GrpcOcelObjectTypeState, GrpcOcelProducedObject, GrpcOcelState, GrpcOcelStateObjectRelation, GrpcPetriNet, - GrpcPetriNetArc, GrpcPetriNetMarking, GrpcPetriNetPlace, GrpcPetriNetSinglePlaceMarking, GrpcPetriNetTransition, GrpcSimpleCounterData, - GrpcSimpleEventLog, GrpcSimpleTrace, GrpcSoftwareData, GrpcSubArrayWithTraceIndex, GrpcSubArraysWithTraceIndexContextValue, GrpcThread, - GrpcThreadEvent, GrpcTimePerformanceAnnotation, GrpcTimeSpan, GrpcTimelineDiagramFragment, GrpcTimelineTraceEventsGroup, - GrpcTraceSubArray, GrpcTraceSubArrays, GrpcTraceTimelineDiagram, GrpcUnderlyingPatternInfo, GrpcUnderlyingPatternKind, - }, - grpc::pipeline_executor::ServicePipelineExecutionContext, pipelines::{ activities_parts::{ActivitiesLogsSourceDto, UndefActivityHandlingStrategyDto}, keys::context_keys::{ @@ -101,7 +101,6 @@ use crate::{ }, }, }; -use chrono::{DateTime, Utc}; use log::error; use nameof::name_of_type; use prost::{DecodeError, Message}; @@ -109,6 +108,8 @@ use prost_types::Timestamp; use std::{any::Any, cell::RefCell, collections::HashMap, fmt::Display, rc::Rc, str::FromStr}; use uuid::Uuid; +use super::pipeline_executor::ServicePipelineExecutionContext; + pub(super) fn context_value_from_bytes(bytes: &[u8]) -> Result { GrpcContextValue::decode(bytes) } @@ -123,10 +124,10 @@ pub(super) fn put_into_user_data( ContextValue::String(string) => user_data.put_any::(key, string.clone()), ContextValue::HashesLog(_) => todo!(), ContextValue::NamesLog(grpc_log) => put_names_log_to_context(key, grpc_log, user_data), - ContextValue::Uint32(number) => user_data.put_any::(key, number.clone()), + ContextValue::Uint32(number) => user_data.put_any::(key, *number), ContextValue::TracesSubArrays(_) => todo!(), ContextValue::TraceIndexSubArrays(_) => todo!(), - ContextValue::Bool(bool) => user_data.put_any::(key, bool.clone()), + ContextValue::Bool(bool) => user_data.put_any::(key, *bool), ContextValue::XesEventLog(grpc_log) => put_names_log_to_context(key, grpc_log, user_data), ContextValue::ColorsLog(_) => {} ContextValue::Enum(grpc_enum) => { @@ -185,7 +186,7 @@ pub(super) fn put_into_user_data( match serde_json::from_str(json_string) { Ok(config) => config, Err(err) => { - error!("Failed to deserialize, error: {}, string: {}", err.to_string(), json_string); + error!("Failed to deserialize, error: {}, string: {}", err, json_string); return; } }, @@ -205,10 +206,10 @@ pub(super) fn put_into_user_data( let mut xes_event = XesEventImpl::new(event.name.to_owned(), date); for attribute in &event.attributes { - let payload_value = match attribute.value.as_ref() { - None => None, - Some(attribute_value) => Some(convert_grpc_event_attribute_to_xes_event_payload_value(attribute_value)), - }; + let payload_value = attribute + .value + .as_ref() + .map(convert_grpc_event_attribute_to_xes_event_payload_value); if let Some(xes_attribute) = payload_value { xes_event.add_or_update_payload(attribute.key.clone(), xes_attribute) @@ -330,17 +331,14 @@ fn convert_to_grpc_ocel_annotation(annotation: &OcelAnnotation) -> GrpcOcelModel .nodes_to_states() .iter() .map(|s| GrpcModelElementOcelAnnotation { - element_id: s.0.clone(), + element_id: *s.0, final_state: Some(convert_to_grpc_ocel_node_state(s.1.final_objects())), - initial_state: match s.1.initial_objects() { - None => None, - Some(objects) => Some(convert_to_grpc_ocel_node_state(objects)), - }, + initial_state: s.1.initial_objects().as_ref().map(convert_to_grpc_ocel_node_state), relations: s .1 .incoming_objects_relations() .iter() - .map(|r| convert_to_grpc_ocel_object_relation(r)) + .map(convert_to_grpc_ocel_object_relation) .collect(), }) .collect(), @@ -609,9 +607,7 @@ fn try_convert_to_grpc_event_log_info(value: &dyn Any) -> Option().unwrap(); - if log_info.counts().is_none() { - return None; - } + log_info.counts()?; Some(GrpcContextValue { context_value: Some(ContextValue::EventLogInfo(GrpcEventLogInfo { @@ -690,16 +686,9 @@ fn convert_to_grpc_arc(arc: &Arc) -> GrpcPetriNetArc { } fn try_convert_to_grpc_marking(marking: Option<&Marking>) -> Option { - match marking { - None => None, - Some(marking) => Some(GrpcPetriNetMarking { - markings: marking - .active_places() - .iter() - .map(|single_marking| convert_to_grpc_single_marking(single_marking)) - .collect(), - }), - } + marking.map(|marking| GrpcPetriNetMarking { + markings: marking.active_places().iter().map(convert_to_grpc_single_marking).collect(), + }) } fn convert_to_grpc_single_marking(marking: &SingleMarking) -> GrpcPetriNetSinglePlaceMarking { @@ -757,22 +746,18 @@ where Some(data) => data.to_string(), }, additional_data: convert_to_grpc_graph_node_additional_data(node.user_data()), - inner_graph: if let Some(inner_graph) = node.user_data.concrete(NODE_INNER_GRAPH_KEY.key()) { - Some(convert_to_grpc_graph(inner_graph)) - } else { - None - }, + inner_graph: node.user_data.concrete(NODE_INNER_GRAPH_KEY.key()).map(convert_to_grpc_graph), } } fn convert_to_grpc_graph_node_additional_data(user_data: &UserDataImpl) -> Vec { let mut additional_data = vec![]; if let Some(software_data) = user_data.concrete(NODE_SOFTWARE_DATA_KEY.key()) { - additional_data.extend(software_data.iter().map(|s| convert_to_grpc_graph_node_software_data(s))); + additional_data.extend(software_data.iter().map(convert_to_grpc_graph_node_software_data)); } if let Some(trace_data) = user_data.concrete(NODE_CORRESPONDING_TRACE_DATA_KEY.key()) { - additional_data.extend(trace_data.iter().map(|t| convert_to_grpc_corresponding_trace_data(t))); + additional_data.extend(trace_data.iter().map(convert_to_grpc_corresponding_trace_data)); } if let Some(activity_start_end_data) = user_data.concrete(NODE_START_END_ACTIVITY_TIME_KEY.key()) { @@ -780,18 +765,14 @@ fn convert_to_grpc_graph_node_additional_data(user_data: &UserDataImpl) -> Vec Vec None => vec![], Some(base_pattern) => base_pattern.clone(), }, - graph: Some(convert_to_grpc_graph(info.graph().as_ref())), + graph: Some(convert_to_grpc_graph(info.graph())), } } @@ -929,8 +910,8 @@ fn convert_to_grpc_node_activity_start_end_data(data: &NodeAdditionalDataContain fn convert_to_grpc_activity_start_end_data(data: &ActivityStartEndTimeData) -> GrpcActivityStartEndData { GrpcActivityStartEndData { - start_time: data.start_time().clone(), - end_time: data.end_time().clone(), + start_time: *data.start_time(), + end_time: *data.end_time(), } } @@ -955,25 +936,21 @@ fn convert_to_grpc_graph_node_software_data(software_data: &NodeAdditionalDataCo fn convert_to_grpc_software_data(software_data: &SoftwareData) -> GrpcSoftwareData { GrpcSoftwareData { histogram: convert_to_grpc_histogram_entries(software_data.event_classes()), - histogram_data: software_data - .histograms() - .iter() - .map(|h| convert_to_grpc_histogram_data(h)) - .collect(), + histogram_data: software_data.histograms().iter().map(convert_to_grpc_histogram_data).collect(), simple_counter_data: software_data .simple_counters() .iter() - .map(|c| convert_to_grpc_simple_counter_data(c)) + .map(convert_to_grpc_simple_counter_data) .collect(), activities_durations_data: software_data .activities_durations() .iter() - .map(|c| convert_to_grpc_activity_duration(c)) + .map(convert_to_grpc_activity_duration) .collect(), - ocel_data: software_data.ocel_data().iter().map(|c| convert_to_grpc_ocel_data(c)).collect(), + ocel_data: software_data.ocel_data().iter().map(convert_to_grpc_ocel_data).collect(), timeline_diagram_fragment: Some(GrpcTimelineDiagramFragment { threads: convert_to_grpc_threads(software_data.thread_diagram_fragment()), @@ -1072,7 +1049,7 @@ where id: *edge.id(), from_node: *edge.from_node(), to_node: *edge.to_node(), - weight: edge.weight, + weight: *edge.weight(), additional_data: convert_to_grpc_edge_additional_data(edge.user_data()), data: match edge.data() { None => "".to_string(), @@ -1107,7 +1084,7 @@ fn convert_to_grpc_edge_additional_data(user_data: &UserDataImpl) -> Vec GrpcGraphEdgeAdditionalData { GrpcGraphEdgeAdditionalData { data: Some(grpc_graph_edge_additional_data::Data::ExecutionInfo(GrpcEdgeExecutionInfo { - trace_id: info.trace_id().clone(), + trace_id: *info.trace_id(), })), } } @@ -1199,7 +1176,7 @@ fn convert_to_grpc_dataset(dataset: &FicusDataset) -> GrpcDataset { fn convert_to_labeled_grpc_dataset(dataset: &LabeledDataset) -> GrpcLabeledDataset { let grpc_dataset = convert_to_grpc_dataset(dataset.dataset()); let labels = dataset.labels().iter().map(|x| *x as i32).collect(); - let labels_colors = dataset.colors().iter().map(|x| convert_to_grpc_color(x)).collect(); + let labels_colors = dataset.colors().iter().map(convert_to_grpc_color).collect(); GrpcLabeledDataset { dataset: Some(grpc_dataset), @@ -1249,7 +1226,7 @@ fn convert_to_grpc_threads(threads: &Vec) -> Vec { .iter() .map(|e| GrpcThreadEvent { name: e.original_event().borrow().name().to_owned(), - stamp: e.stamp().clone(), + stamp: *e.stamp(), }) .collect(), }) @@ -1258,7 +1235,7 @@ fn convert_to_grpc_threads(threads: &Vec) -> Vec { fn convert_to_grpc_log_point(point: &LogPoint) -> GrpcLogPoint { GrpcLogPoint { - trace_index: point.trace_index().clone() as u64, - event_index: point.event_index().clone() as u64, + trace_index: *point.trace_index() as u64, + event_index: *point.event_index() as u64, } } diff --git a/Ficus/src/rust/ficus/src/grpc/events/delegating_events_handler.rs b/Ficus/src/rust/ficus_backend/src/grpc/events/delegating_events_handler.rs similarity index 87% rename from Ficus/src/rust/ficus/src/grpc/events/delegating_events_handler.rs rename to Ficus/src/rust/ficus_backend/src/grpc/events/delegating_events_handler.rs index 002d09dd5..b99413f06 100644 --- a/Ficus/src/rust/ficus/src/grpc/events/delegating_events_handler.rs +++ b/Ficus/src/rust/ficus_backend/src/grpc/events/delegating_events_handler.rs @@ -18,6 +18,6 @@ impl PipelineEventsHandler for DelegatingEventsHandler { } fn is_alive(&self) -> bool { - self.handlers.iter().map(|h| h.is_alive()).fold(true, |a, b| a && b) + self.handlers.iter().all(|h| h.is_alive()) } } diff --git a/Ficus/src/rust/ficus/src/grpc/events/events_handler.rs b/Ficus/src/rust/ficus_backend/src/grpc/events/events_handler.rs similarity index 60% rename from Ficus/src/rust/ficus/src/grpc/events/events_handler.rs rename to Ficus/src/rust/ficus_backend/src/grpc/events/events_handler.rs index d28c459c3..9f9f3294b 100644 --- a/Ficus/src/rust/ficus/src/grpc/events/events_handler.rs +++ b/Ficus/src/rust/ficus_backend/src/grpc/events/events_handler.rs @@ -1,9 +1,9 @@ use std::any::Any; +use crate::grpc::events::kafka_events_handler::ProcessCaseMetadata; +use ficus::utils::context_key::ContextKey; use uuid::Uuid; -use crate::utils::context_key::ContextKey; - pub trait PipelineEventsHandler: Send + Sync { fn handle(&self, event: &PipelineEvent); fn is_alive(&self) -> bool; @@ -33,31 +33,6 @@ pub struct GetContextValuesEvent<'a> { pub key_values: Vec<(&'a dyn ContextKey, &'a dyn Any)>, } -#[derive(Clone, Debug)] -pub struct CaseName { - pub display_name: String, - pub name_parts: Vec, -} - -impl CaseName { - pub fn empty() -> Self { - Self { - name_parts: vec![], - display_name: "UNDEFINED".to_string(), - } - } -} - -pub struct ProcessCaseMetadata { - pub case_name: CaseName, - pub process_name: String, - pub subscription_id: Option, - pub subscription_name: Option, - pub pipeline_id: Option, - pub pipeline_name: Option, - pub metadata: Vec<(String, String)>, -} - pub enum PipelineFinalResult { Success(Uuid), Error(String), diff --git a/Ficus/src/rust/ficus/src/grpc/events/grpc_events_handler.rs b/Ficus/src/rust/ficus_backend/src/grpc/events/grpc_events_handler.rs similarity index 97% rename from Ficus/src/rust/ficus/src/grpc/events/grpc_events_handler.rs rename to Ficus/src/rust/ficus_backend/src/grpc/events/grpc_events_handler.rs index a75b01931..844c51068 100644 --- a/Ficus/src/rust/ficus/src/grpc/events/grpc_events_handler.rs +++ b/Ficus/src/rust/ficus_backend/src/grpc/events/grpc_events_handler.rs @@ -11,9 +11,8 @@ use crate::{ events::utils::{create_grpc_context_values, send_grpc_message}, logs_handler::ConsoleLogMessageHandler, }, - pipelines::context::LogMessageHandler, }; - +use ficus::pipelines::context::LogMessageHandler; pub struct GrpcPipelineEventsHandler { sender: Arc>, console_logs_handler: ConsoleLogMessageHandler, @@ -32,7 +31,7 @@ impl PipelineEventsHandler for GrpcPipelineEventsHandler { fn handle(&self, event: &PipelineEvent) { let result = match event { PipelineEvent::GetContextValuesEvent(event) => self.create_get_context_values_event(event), - PipelineEvent::LogMessage(message) => self.create_log_message_result(&message), + PipelineEvent::LogMessage(message) => self.create_log_message_result(message), PipelineEvent::FinalResult(result) => self.create_final_result(match result { PipelineFinalResult::Success(uuid) => ExecutionResult::Success(GrpcGuid { guid: uuid.to_string() }), PipelineFinalResult::Error(error_message) => ExecutionResult::Error(error_message.to_string()), diff --git a/Ficus/src/rust/ficus/src/grpc/events/kafka_events_handler.rs b/Ficus/src/rust/ficus_backend/src/grpc/events/kafka_events_handler.rs similarity index 87% rename from Ficus/src/rust/ficus/src/grpc/events/kafka_events_handler.rs rename to Ficus/src/rust/ficus_backend/src/grpc/events/kafka_events_handler.rs index 1426930c6..00273ffd6 100644 --- a/Ficus/src/rust/ficus/src/grpc/events/kafka_events_handler.rs +++ b/Ficus/src/rust/ficus_backend/src/grpc/events/kafka_events_handler.rs @@ -1,11 +1,11 @@ -use super::events_handler::{GetContextValuesEvent, PipelineEvent, PipelineEventsHandler, PipelineFinalResult, ProcessCaseMetadata}; +use super::events_handler::{GetContextValuesEvent, PipelineEvent, PipelineEventsHandler, PipelineFinalResult}; use crate::{ ficus_proto::{ GrpcCaseName, GrpcGuid, GrpcKafkaConnectionMetadata, GrpcKafkaUpdate, GrpcPipelinePartInfo, GrpcProcessCaseMetadata, GrpcStringKeyValue, }, grpc::{events::utils::create_grpc_context_values, logs_handler::ConsoleLogMessageHandler}, - pipelines::context::LogMessageHandler, }; +use ficus::{features::cases::CaseName, pipelines::context::LogMessageHandler}; use prost::Message; use rdkafka::{ error::KafkaError, @@ -28,10 +28,7 @@ impl PipelineEventsProducer { config.set(kv_pair.key.clone(), kv_pair.value.clone()); } - let producer = match config.create() { - Ok(producer) => producer, - Err(err) => return Err(err), - }; + let producer = config.create()?; Ok(Self { topic_name: connection_metadata.topic_name.to_owned(), @@ -80,7 +77,7 @@ impl PipelineEventsHandler for KafkaEventsHandler { let message = match result { Ok(_) => "Sent message to kafka".to_string(), - Err(err) => format!("Failed to produce event: {}", err.to_string()), + Err(err) => format!("Failed to produce event: {}", err), }; self.console_logs_handler.handle(message.as_str()).expect("Should log message"); @@ -119,6 +116,16 @@ impl GetContextValuesEvent<'_> { } } +pub struct ProcessCaseMetadata { + pub case_name: CaseName, + pub process_name: String, + pub subscription_id: Option, + pub subscription_name: Option, + pub pipeline_id: Option, + pub pipeline_name: Option, + pub metadata: Vec<(String, String)>, +} + impl ProcessCaseMetadata { fn to_grpc_process_case_metadata(&self) -> GrpcProcessCaseMetadata { GrpcProcessCaseMetadata { @@ -128,9 +135,9 @@ impl ProcessCaseMetadata { }), process_name: self.process_name.clone(), - subscription_id: self.subscription_id.map(|id| GrpcGuid::from(id.clone())), + subscription_id: self.subscription_id.map(GrpcGuid::from), subscription_name: self.subscription_name.clone().map_or("".to_string(), |name| name), - pipeline_id: self.pipeline_id.map(|id| GrpcGuid::from(id.clone())), + pipeline_id: self.pipeline_id.map(GrpcGuid::from), pipeline_name: self.pipeline_name.clone().map_or("".to_string(), |name| name), metadata: self diff --git a/Ficus/src/rust/ficus/src/grpc/events/mod.rs b/Ficus/src/rust/ficus_backend/src/grpc/events/mod.rs similarity index 100% rename from Ficus/src/rust/ficus/src/grpc/events/mod.rs rename to Ficus/src/rust/ficus_backend/src/grpc/events/mod.rs diff --git a/Ficus/src/rust/ficus/src/grpc/events/utils.rs b/Ficus/src/rust/ficus_backend/src/grpc/events/utils.rs similarity index 91% rename from Ficus/src/rust/ficus/src/grpc/events/utils.rs rename to Ficus/src/rust/ficus_backend/src/grpc/events/utils.rs index 95e24e1af..3e64f9394 100644 --- a/Ficus/src/rust/ficus/src/grpc/events/utils.rs +++ b/Ficus/src/rust/ficus_backend/src/grpc/events/utils.rs @@ -1,9 +1,8 @@ use crate::{ ficus_proto::GrpcContextValueWithKeyName, grpc::{converters::convert_to_grpc_context_value, logs_handler::ConsoleLogMessageHandler}, - pipelines::context::LogMessageHandler, - utils::context_key::ContextKey, }; +use ficus::{pipelines::context::LogMessageHandler, utils::context_key::ContextKey}; use std::any::Any; use tokio::sync::mpsc::Sender; use tonic::Status; @@ -25,7 +24,7 @@ pub(super) fn send_grpc_message(sender: &Sender>, logs_hand match sender.blocking_send(Ok(value)) { Ok(_) => {} Err(err) => { - let message = format!("Failed to send event, error: {}", err.to_string()); + let message = format!("Failed to send event, error: {}", err); logs_handler.handle(message.as_str()).ok(); } } diff --git a/Ficus/src/rust/ficus/src/grpc/get_context_pipeline.rs b/Ficus/src/rust/ficus_backend/src/grpc/get_context_pipeline.rs similarity index 87% rename from Ficus/src/rust/ficus/src/grpc/get_context_pipeline.rs rename to Ficus/src/rust/ficus_backend/src/grpc/get_context_pipeline.rs index b20d84e5d..1cf07297c 100644 --- a/Ficus/src/rust/ficus/src/grpc/get_context_pipeline.rs +++ b/Ficus/src/rust/ficus_backend/src/grpc/get_context_pipeline.rs @@ -1,8 +1,10 @@ use std::{any::Any, sync::Arc}; use uuid::Uuid; -use super::events::events_handler::{CaseName, GetContextValuesEvent, PipelineEvent, PipelineEventsHandler, ProcessCaseMetadata}; -use crate::{ +use super::events::events_handler::{GetContextValuesEvent, PipelineEvent, PipelineEventsHandler}; +use crate::grpc::events::kafka_events_handler::ProcessCaseMetadata; +use ficus::{ + features::cases::CaseName, pipelines::{ context::{PipelineContext, PipelineInfrastructure}, errors::pipeline_errors::{MissingContextError, PipelinePartExecutionError, RawPartExecutionError}, @@ -80,7 +82,7 @@ impl GetContextValuePipelinePart { } fn create_process_case_metadata(context: &PipelineContext) -> ProcessCaseMetadata { - let case_name = Self::value_or_default(context, &CASE_NAME_KEY, || CaseName::empty()); + let case_name = Self::value_or_default(context, &CASE_NAME_KEY, CaseName::empty); let process_name = Self::value_or_default(context, &PROCESS_NAME_KEY, || "UNDEFINED_PROCESS".to_string()); let subscription_id = Self::value_or_none(context, &SUBSCRIPTION_ID_KEY); @@ -89,7 +91,7 @@ impl GetContextValuePipelinePart { let pipeline_id = Self::value_or_none(context, &PIPELINE_ID_KEY); let pipeline_name = Self::value_or_none(context, &PIPELINE_NAME_KEY); - let metadata = Self::value_or_default(context, &UNSTRUCTURED_METADATA_KEY, || vec![]); + let metadata = Self::value_or_default(context, &UNSTRUCTURED_METADATA_KEY, std::vec::Vec::new); ProcessCaseMetadata { process_name, @@ -102,18 +104,15 @@ impl GetContextValuePipelinePart { } } - fn value_or_default<'a, T: Clone>(context: &'a PipelineContext, key: &DefaultContextKey, default_factory: impl Fn() -> T) -> T { + fn value_or_default(context: &PipelineContext, key: &DefaultContextKey, default_factory: impl Fn() -> T) -> T { match context.concrete(key.key()) { None => default_factory(), Some(value) => value.clone(), } } - fn value_or_none<'a, T: Clone>(context: &'a PipelineContext, key: &DefaultContextKey) -> Option { - match context.concrete(key.key()) { - None => None, - Some(value) => Some(value.clone()), - } + fn value_or_none(context: &PipelineContext, key: &DefaultContextKey) -> Option { + context.concrete(key.key()).cloned() } fn find_context_values_for<'a>( @@ -152,6 +151,6 @@ impl PipelinePart for GetContextValuePipelinePart { } } - (self.handler)(self.uuid.clone(), self.pipeline_part_name.to_owned(), context, infra, context_keys) + (self.handler)(self.uuid, self.pipeline_part_name.to_owned(), context, infra, context_keys) } } diff --git a/Ficus/src/rust/ficus/src/utils/grpc_utils.rs b/Ficus/src/rust/ficus_backend/src/grpc/grpc_utils.rs similarity index 100% rename from Ficus/src/rust/ficus/src/utils/grpc_utils.rs rename to Ficus/src/rust/ficus_backend/src/grpc/grpc_utils.rs diff --git a/Ficus/src/rust/ficus/src/grpc/kafka/grpc_kafka_service.rs b/Ficus/src/rust/ficus_backend/src/grpc/kafka/grpc_kafka_service.rs similarity index 97% rename from Ficus/src/rust/ficus/src/grpc/kafka/grpc_kafka_service.rs rename to Ficus/src/rust/ficus_backend/src/grpc/kafka/grpc_kafka_service.rs index 3bdce8a72..6ac27912f 100644 --- a/Ficus/src/rust/ficus/src/grpc/kafka/grpc_kafka_service.rs +++ b/Ficus/src/rust/ficus_backend/src/grpc/kafka/grpc_kafka_service.rs @@ -10,11 +10,14 @@ use crate::{ context_values_service::ContextValueService, events::{ delegating_events_handler::DelegatingEventsHandler, - events_handler::{CaseName, PipelineEvent, PipelineEventsHandler, PipelineFinalResult}, + events_handler::{PipelineEvent, PipelineEventsHandler, PipelineFinalResult}, grpc_events_handler::GrpcPipelineEventsHandler, }, kafka::{kafka_service::KafkaService, models::PipelineExecutionDto}, }, +}; +use ficus::{ + features::cases::CaseName, pipelines::{ keys::context_keys::{CASE_NAME_KEY, PIPELINE_ID_KEY, PIPELINE_NAME_KEY, PROCESS_NAME_KEY, SUBSCRIPTION_ID_KEY, SUBSCRIPTION_NAME_KEY}, pipeline_parts::PipelineParts, @@ -121,7 +124,7 @@ impl GrpcKafkaService for GrpcKafkaServiceImpl { self.kafka_service.remove_execution_request(&subscription_id, &pipeline_id); - Ok(Response::new(GrpcKafkaResult::success(pipeline_id.clone()))) + Ok(Response::new(GrpcKafkaResult::success(pipeline_id))) } async fn remove_all_pipeline_subscriptions( @@ -137,7 +140,7 @@ impl GrpcKafkaService for GrpcKafkaServiceImpl { self.kafka_service.remove_all_execution_requests(&subscription_id); - Ok(Response::new(GrpcKafkaResult::success(subscription_id.clone()))) + Ok(Response::new(GrpcKafkaResult::success(subscription_id))) } async fn get_all_subscriptions_and_pipelines( diff --git a/Ficus/src/rust/ficus/src/grpc/kafka/kafka_service.rs b/Ficus/src/rust/ficus_backend/src/grpc/kafka/kafka_service.rs similarity index 94% rename from Ficus/src/rust/ficus/src/grpc/kafka/kafka_service.rs rename to Ficus/src/rust/ficus_backend/src/grpc/kafka/kafka_service.rs index 4b612065f..5f5f310df 100644 --- a/Ficus/src/rust/ficus/src/grpc/kafka/kafka_service.rs +++ b/Ficus/src/rust/ficus_backend/src/grpc/kafka/kafka_service.rs @@ -18,6 +18,9 @@ use crate::{ logs_handler::ConsoleLogMessageHandler, pipeline_executor::ServicePipelineExecutionContext, }, +}; +use bxes_kafka::consumer::bxes_kafka_consumer::{BxesKafkaConsumer, BxesKafkaError, BxesKafkaTrace}; +use ficus::{ pipelines::{ context::LogMessageHandler, errors::pipeline_errors::{PipelinePartExecutionError, RawPartExecutionError}, @@ -26,7 +29,6 @@ use crate::{ }, utils::user_data::user_data::UserData, }; -use bxes_kafka::consumer::bxes_kafka_consumer::{BxesKafkaConsumer, BxesKafkaError, BxesKafkaTrace}; use log::error; use rdkafka::{error::KafkaError, ClientConfig}; use std::{ @@ -79,7 +81,7 @@ impl KafkaSubscription { self.name.clone() } pub fn pipelines(&self) -> Vec<(Uuid, KafkaSubscriptionPipeline)> { - self.pipelines.iter().map(|p| (p.0.clone(), p.1.clone())).collect() + self.pipelines.iter().map(|p| (*p.0, p.1.clone())).collect() } } @@ -123,7 +125,7 @@ impl KafkaService { pub(super) fn subscribe_to_kafka_topic(&self, request: GrpcSubscribeToKafkaRequest) -> Result { let name = request.subscription_metadata.as_ref().unwrap().subscription_name.clone(); let creation_dto = self.create_kafka_creation_dto(name); - let id = creation_dto.uuid.clone(); + let id = creation_dto.uuid; match Self::spawn_consumer(request, creation_dto) { Ok(_) => Ok(id), @@ -135,7 +137,7 @@ impl KafkaService { let mut consumer = match Self::create_consumer(&request) { Ok(consumer) => consumer, Err(err) => { - error!("Failed to create kafka consumer: {}", err.to_string()); + error!("Failed to create kafka consumer: {}", err); return Err(err); } }; @@ -143,7 +145,7 @@ impl KafkaService { match consumer.subscribe() { Ok(_) => { let mut map = dto.subscriptions_to_execution_requests.lock().expect("Must acquire lock"); - map.insert(dto.uuid.clone(), KafkaSubscription::new(dto.name.clone())); + map.insert(dto.uuid, KafkaSubscription::new(dto.name.clone())); } Err(err) => { return match err { @@ -192,10 +194,11 @@ impl KafkaService { } match consumer.consume() { - Ok(trace) => match trace { - Some(trace) => Self::process_kafka_trace(trace, dto), - None => {} - }, + Ok(trace) => { + if let Some(trace) = trace { + Self::process_kafka_trace(trace, dto) + } + } Err(err) => { print!("Failed to read messages from kafka: {:?}", err) } @@ -239,7 +242,7 @@ impl KafkaService { match pipeline.processor.observe(trace_processing_context) { Ok(()) => {} Err(err) => { - let message = format!("Failed to get update result, err: {}", err.to_string()); + let message = format!("Failed to get update result, err: {}", err); dto.logger.handle(message.as_str()).expect("Must log message"); return Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new( "Failed to mutate context".to_string(), @@ -247,8 +250,8 @@ impl KafkaService { } }; - context.put_concrete(SUBSCRIPTION_ID_KEY.key(), dto.uuid.clone()); - context.put_concrete(PIPELINE_ID_KEY.key(), pipeline_id.clone()); + context.put_concrete(SUBSCRIPTION_ID_KEY.key(), dto.uuid); + context.put_concrete(PIPELINE_ID_KEY.key(), *pipeline_id); context.put_concrete(SUBSCRIPTION_NAME_KEY.key(), dto.name.clone()); context.put_concrete(PIPELINE_NAME_KEY.key(), pipeline.name.clone()); @@ -274,7 +277,7 @@ impl KafkaService { ) -> Uuid { let mut map = self.subscriptions_to_execution_requests.lock().expect("Must acquire lock"); let pipeline_id = Uuid::new_v4(); - let streaming_config = StreamingConfiguration::new(&streaming_config).unwrap_or_else(|| StreamingConfiguration::NotSpecified); + let streaming_config = StreamingConfiguration::new(&streaming_config).unwrap_or(StreamingConfiguration::NotSpecified); let kafka_pipeline = self.create_kafka_pipeline(request, handler, pipeline_name, streaming_config); match map.get_mut(&subscription_id) { @@ -317,7 +320,7 @@ impl KafkaService { pub fn get_all_subscriptions(&self) -> Vec<(Uuid, KafkaSubscription)> { let map = self.subscriptions_to_execution_requests.lock().expect("Must acquire lock"); - map.iter().map(|s| (s.0.clone(), s.1.clone())).collect() + map.iter().map(|s| (*s.0, s.1.clone())).collect() } } @@ -357,7 +360,7 @@ impl KafkaService { let producer = match PipelineEventsProducer::create(producer_metadata) { Ok(producer) => producer, Err(err) => { - let message = format!("Failed to create producer: {}", err.to_string()); + let message = format!("Failed to create producer: {}", err); return Err(Status::invalid_argument(message)); } }; diff --git a/Ficus/src/rust/ficus/src/grpc/kafka/mod.rs b/Ficus/src/rust/ficus_backend/src/grpc/kafka/mod.rs similarity index 100% rename from Ficus/src/rust/ficus/src/grpc/kafka/mod.rs rename to Ficus/src/rust/ficus_backend/src/grpc/kafka/mod.rs diff --git a/Ficus/src/rust/ficus/src/grpc/kafka/models.rs b/Ficus/src/rust/ficus_backend/src/grpc/kafka/models.rs similarity index 80% rename from Ficus/src/rust/ficus/src/grpc/kafka/models.rs rename to Ficus/src/rust/ficus_backend/src/grpc/kafka/models.rs index e67d1d27a..b08a87512 100644 --- a/Ficus/src/rust/ficus/src/grpc/kafka/models.rs +++ b/Ficus/src/rust/ficus_backend/src/grpc/kafka/models.rs @@ -1,6 +1,8 @@ -use crate::{ +use crate::grpc::{ + events::events_handler::PipelineEventsHandler, kafka::kafka_service::KafkaSubscription, logs_handler::ConsoleLogMessageHandler, +}; +use ficus::{ event_log::bxes::bxes_to_xes_converter::BxesToXesReadError, - grpc::{events::events_handler::PipelineEventsHandler, kafka::kafka_service::KafkaSubscription, logs_handler::ConsoleLogMessageHandler}, pipelines::{errors::pipeline_errors::PipelinePartExecutionError, pipeline_parts::PipelineParts}, }; use std::{ @@ -10,12 +12,12 @@ use std::{ }; use uuid::Uuid; -pub(super) const KAFKA_CASE_DISPLAY_NAME: &'static str = "case_display_name"; -pub(super) const KAFKA_CASE_NAME_PARTS: &'static str = "case_name_parts"; -pub(super) const KAFKA_CASE_ID: &'static str = "case_id"; -pub(super) const KAFKA_CASE_NAME_PARTS_SEPARATOR: &'static str = ";"; -pub(super) const KAFKA_PROCESS_NAME: &'static str = "process_name"; -pub(super) const KAFKA_TRACE_ID: &'static str = "trace_id"; +pub(super) const KAFKA_CASE_DISPLAY_NAME: &str = "case_display_name"; +pub(super) const KAFKA_CASE_NAME_PARTS: &str = "case_name_parts"; +pub(super) const KAFKA_CASE_ID: &str = "case_id"; +pub(super) const KAFKA_CASE_NAME_PARTS_SEPARATOR: &str = ";"; +pub(super) const KAFKA_PROCESS_NAME: &str = "process_name"; +pub(super) const KAFKA_TRACE_ID: &str = "trace_id"; #[derive(Debug)] pub enum KafkaTraceProcessingError { @@ -48,7 +50,7 @@ impl Display for XesFromBxesKafkaTraceCreatingError { format!("Value for key {} is not a String", key_name.to_owned()) } XesFromBxesKafkaTraceCreatingError::MetadataValueNotFound(key_name) => { - format!("The key {} is not found", key_name.to_string()) + format!("The key {} is not found", key_name) } XesFromBxesKafkaTraceCreatingError::TraceIdIsNotUuid => "Trace id was not of type uuid ".to_string(), }; diff --git a/Ficus/src/rust/ficus/src/grpc/kafka/streaming/configs.rs b/Ficus/src/rust/ficus_backend/src/grpc/kafka/streaming/configs.rs similarity index 69% rename from Ficus/src/rust/ficus/src/grpc/kafka/streaming/configs.rs rename to Ficus/src/rust/ficus_backend/src/grpc/kafka/streaming/configs.rs index c515c4eae..1a0f7c335 100644 --- a/Ficus/src/rust/ficus/src/grpc/kafka/streaming/configs.rs +++ b/Ficus/src/rust/ficus_backend/src/grpc/kafka/streaming/configs.rs @@ -2,14 +2,14 @@ use crate::{ ficus_proto::GrpcPipelineStreamingConfiguration, grpc::kafka::streaming::{ processors::TracesProcessor, - t1::{ - configs::{T1StreamingConfiguration, TracesQueueConfiguration}, - filterers::{T1LogFilterer, TracesQueueFiltererImpl}, - processors::T1StreamingProcessor, - }, + t1::{configs::T1StreamingConfiguration, processors::T1StreamingProcessor}, t2::configs::T2StreamingConfiguration, }, }; +use ficus::features::streaming::t1::{ + configs::TracesQueueConfiguration, + filterers::{T1LogFilterer, TracesQueueFiltererImpl}, +}; type StreamingConfigurationEnum = crate::ficus_proto::grpc_pipeline_streaming_configuration::Configuration; @@ -25,14 +25,8 @@ impl StreamingConfiguration { None => None, Some(c) => match c { StreamingConfigurationEnum::NotSpecified(_) => Some(StreamingConfiguration::NotSpecified), - StreamingConfigurationEnum::T1Configuration(t1) => match T1StreamingConfiguration::new(t1) { - None => None, - Some(t1) => Some(StreamingConfiguration::T1(t1)), - }, - StreamingConfigurationEnum::T2Configuration(t2) => match T2StreamingConfiguration::new(t2) { - None => None, - Some(t2) => Some(StreamingConfiguration::T2(t2)), - }, + StreamingConfigurationEnum::T1Configuration(t1) => T1StreamingConfiguration::new(t1).map(StreamingConfiguration::T1), + StreamingConfigurationEnum::T2Configuration(t2) => T2StreamingConfiguration::new(t2).map(StreamingConfiguration::T2), }, } } diff --git a/Ficus/src/rust/ficus/src/grpc/kafka/streaming/mod.rs b/Ficus/src/rust/ficus_backend/src/grpc/kafka/streaming/mod.rs similarity index 100% rename from Ficus/src/rust/ficus/src/grpc/kafka/streaming/mod.rs rename to Ficus/src/rust/ficus_backend/src/grpc/kafka/streaming/mod.rs diff --git a/Ficus/src/rust/ficus/src/grpc/kafka/streaming/processors.rs b/Ficus/src/rust/ficus_backend/src/grpc/kafka/streaming/processors.rs similarity index 87% rename from Ficus/src/rust/ficus/src/grpc/kafka/streaming/processors.rs rename to Ficus/src/rust/ficus_backend/src/grpc/kafka/streaming/processors.rs index bff421019..99e8c19e8 100644 --- a/Ficus/src/rust/ficus/src/grpc/kafka/streaming/processors.rs +++ b/Ficus/src/rust/ficus_backend/src/grpc/kafka/streaming/processors.rs @@ -1,22 +1,20 @@ -use crate::{ - grpc::{ - events::events_handler::CaseName, - kafka::{ - models::{ - KafkaTraceProcessingError, PipelineExecutionDto, XesFromBxesKafkaTraceCreatingError, KAFKA_CASE_DISPLAY_NAME, KAFKA_CASE_ID, - KAFKA_CASE_NAME_PARTS, KAFKA_CASE_NAME_PARTS_SEPARATOR, KAFKA_PROCESS_NAME, - }, - streaming::{t1::processors::T1StreamingProcessor, t2::processors::T2StreamingProcessor}, - }, +use crate::grpc::kafka::{ + models::{ + KafkaTraceProcessingError, PipelineExecutionDto, XesFromBxesKafkaTraceCreatingError, KAFKA_CASE_DISPLAY_NAME, KAFKA_CASE_ID, + KAFKA_CASE_NAME_PARTS, KAFKA_CASE_NAME_PARTS_SEPARATOR, KAFKA_PROCESS_NAME, }, + streaming::{t1::processors::T1StreamingProcessor, t2::processors::T2StreamingProcessor}, +}; +use bxes::models::domain::bxes_value::BxesValue; +use bxes_kafka::consumer::bxes_kafka_consumer::BxesKafkaTrace; +use ficus::{ + features::cases::CaseName, pipelines::{ context::PipelineContext, keys::context_keys::{CASE_NAME_KEY, PROCESS_NAME_KEY, UNSTRUCTURED_METADATA_KEY}, }, utils::user_data::user_data::UserData, }; -use bxes::models::domain::bxes_value::BxesValue; -use bxes_kafka::consumer::bxes_kafka_consumer::BxesKafkaTrace; use std::{collections::HashMap, rc::Rc}; use uuid::Uuid; @@ -149,7 +147,7 @@ pub(in crate::grpc::kafka::streaming) fn uuid_or_err( ) -> Result { let value = value_or_err(metadata, key)?; if let BxesValue::Guid(id) = value.as_ref().as_ref() { - Ok(id.clone()) + Ok(*id) } else { Err(XesFromBxesKafkaTraceCreatingError::TraceIdIsNotUuid) } @@ -160,18 +158,14 @@ pub(in crate::grpc::kafka::streaming) fn metadata_to_string_string_pairs( ) -> Vec<(String, String)> { metadata .iter() - .map(|pair| { + .filter_map(|pair| { if pair.0 == KAFKA_CASE_NAME_PARTS || pair.0 == KAFKA_CASE_DISPLAY_NAME || pair.0 == KAFKA_PROCESS_NAME { None + } else if let BxesValue::String(value) = pair.1.as_ref().as_ref() { + Some((pair.0.to_owned(), value.as_ref().as_ref().to_owned())) } else { - if let BxesValue::String(value) = pair.1.as_ref().as_ref() { - Some((pair.0.to_owned(), value.as_ref().as_ref().to_owned())) - } else { - None - } + None } }) - .filter(|kv| kv.is_some()) - .map(|kv| kv.unwrap()) .collect() } diff --git a/Ficus/src/rust/ficus_backend/src/grpc/kafka/streaming/t1/configs.rs b/Ficus/src/rust/ficus_backend/src/grpc/kafka/streaming/t1/configs.rs new file mode 100644 index 000000000..df2ce493d --- /dev/null +++ b/Ficus/src/rust/ficus_backend/src/grpc/kafka/streaming/t1/configs.rs @@ -0,0 +1,38 @@ +use crate::{ + ficus_proto::{grpc_t1_streaming_configuration::Configuration, GrpcT1StreamingConfiguration}, + grpc::kafka::streaming::t1::processors::T1StreamingProcessor, +}; +use ficus::features::streaming::t1::{ + configs::{EventsTimeoutConfiguration, TracesQueueConfiguration, TracesTimeoutConfiguration}, + filterers::{EventsTimeoutFiltererImpl, T1LogFilterer, TracesQueueFiltererImpl, TracesTimeoutFiltererImpl}, +}; + +pub enum T1StreamingConfiguration { + EventsTimeout(EventsTimeoutConfiguration), + TracesTimeout(TracesTimeoutConfiguration), + TracesQueue(TracesQueueConfiguration), +} + +impl T1StreamingConfiguration { + pub fn new(grpc_config: &GrpcT1StreamingConfiguration) -> Option { + grpc_config.configuration.as_ref().map(|c| match c { + Configuration::EventsTimeout(et) => { + T1StreamingConfiguration::EventsTimeout(EventsTimeoutConfiguration::new(et.events_timeout_ms as u64)) + } + Configuration::TracesTimeout(tt) => { + T1StreamingConfiguration::TracesTimeout(TracesTimeoutConfiguration::new(tt.traces_timeout_ms as u64)) + } + Configuration::TracesQueueConfiguration(tq) => { + T1StreamingConfiguration::TracesQueue(TracesQueueConfiguration::new(tq.queue_capacity as u64)) + } + }) + } + + pub fn create_processor(&self) -> T1StreamingProcessor { + T1StreamingProcessor::new(match self { + T1StreamingConfiguration::EventsTimeout(c) => T1LogFilterer::EventsTimeoutFilterer(EventsTimeoutFiltererImpl::new(c.clone())), + T1StreamingConfiguration::TracesTimeout(c) => T1LogFilterer::TracesTimeoutFilterer(TracesTimeoutFiltererImpl::new(c.clone())), + T1StreamingConfiguration::TracesQueue(c) => T1LogFilterer::TracesQueueFilterer(TracesQueueFiltererImpl::new(c.clone())), + }) + } +} diff --git a/Ficus/src/rust/ficus/src/grpc/kafka/streaming/t1/mod.rs b/Ficus/src/rust/ficus_backend/src/grpc/kafka/streaming/t1/mod.rs similarity index 66% rename from Ficus/src/rust/ficus/src/grpc/kafka/streaming/t1/mod.rs rename to Ficus/src/rust/ficus_backend/src/grpc/kafka/streaming/t1/mod.rs index 0cb28e0d7..9897da05f 100644 --- a/Ficus/src/rust/ficus/src/grpc/kafka/streaming/t1/mod.rs +++ b/Ficus/src/rust/ficus_backend/src/grpc/kafka/streaming/t1/mod.rs @@ -1,3 +1,2 @@ pub mod configs; -pub mod filterers; pub mod processors; diff --git a/Ficus/src/rust/ficus/src/grpc/kafka/streaming/t1/processors.rs b/Ficus/src/rust/ficus_backend/src/grpc/kafka/streaming/t1/processors.rs similarity index 90% rename from Ficus/src/rust/ficus/src/grpc/kafka/streaming/t1/processors.rs rename to Ficus/src/rust/ficus_backend/src/grpc/kafka/streaming/t1/processors.rs index ee5b3dc24..1b5b266d6 100644 --- a/Ficus/src/rust/ficus/src/grpc/kafka/streaming/t1/processors.rs +++ b/Ficus/src/rust/ficus_backend/src/grpc/kafka/streaming/t1/processors.rs @@ -1,26 +1,24 @@ -use crate::{ +use crate::grpc::{ + kafka::{ + models::{KafkaTraceProcessingError, XesFromBxesKafkaTraceCreatingError, KAFKA_CASE_ID, KAFKA_CASE_NAME_PARTS, KAFKA_TRACE_ID}, + streaming::processors::{string_value_or_err, uuid_or_err}, + }, + logs_handler::ConsoleLogMessageHandler, +}; +use bxes_kafka::consumer::bxes_kafka_consumer::BxesKafkaTrace; +use ficus::{ event_log::{ bxes::bxes_to_xes_converter::read_bxes_events, core::{event::event::EventPayloadValue, event_log::EventLog, trace::trace::Trace}, xes::{xes_event_log::XesEventLogImpl, xes_trace::XesTraceImpl}, }, - grpc::{ - kafka::{ - models::{KafkaTraceProcessingError, XesFromBxesKafkaTraceCreatingError, KAFKA_CASE_ID, KAFKA_CASE_NAME_PARTS, KAFKA_TRACE_ID}, - streaming::{ - processors::{string_value_or_err, uuid_or_err}, - t1::filterers::T1LogFilterer, - }, - }, - logs_handler::ConsoleLogMessageHandler, - }, + features::streaming::t1::filterers::T1LogFilterer, pipelines::{ context::{LogMessageHandler, PipelineContext}, keys::context_keys::EVENT_LOG_KEY, }, utils::user_data::user_data::UserData, }; -use bxes_kafka::consumer::bxes_kafka_consumer::BxesKafkaTrace; use log::info; use std::{ cell::RefCell, @@ -54,7 +52,7 @@ impl T1StreamingProcessor { Ok(()) } Err(err) => { - let message = format!("Failed to get update result, err: {}", err.to_string()); + let message = format!("Failed to get update result, err: {}", err); self.logger.handle(message.as_str()).expect("Must log message"); Err(KafkaTraceProcessingError::XesFromBxesTraceCreationError(err)) } @@ -98,7 +96,7 @@ impl T1StreamingProcessor { for existing_xes_trace in existing_log.traces() { let mut existing_xes_trace = existing_xes_trace.borrow_mut(); - if let Some(current_trace_id) = Self::try_get_trace_id(&existing_xes_trace).clone() { + if let Some(current_trace_id) = Self::try_get_trace_id(&existing_xes_trace) { if current_trace_id == trace_id { info!("Found an existing trace for trace id {}, appending it", current_trace_id); @@ -126,7 +124,7 @@ impl T1StreamingProcessor { fn try_get_trace_id(trace: &XesTraceImpl) -> Option { if let Some(EventPayloadValue::Guid(id)) = trace.metadata().get(KAFKA_TRACE_ID) { - Some(id.clone()) + Some(*id) } else { None } diff --git a/Ficus/src/rust/ficus/src/grpc/kafka/streaming/t2/configs.rs b/Ficus/src/rust/ficus_backend/src/grpc/kafka/streaming/t2/configs.rs similarity index 66% rename from Ficus/src/rust/ficus/src/grpc/kafka/streaming/t2/configs.rs rename to Ficus/src/rust/ficus_backend/src/grpc/kafka/streaming/t2/configs.rs index ecb075782..26e02b007 100644 --- a/Ficus/src/rust/ficus/src/grpc/kafka/streaming/t2/configs.rs +++ b/Ficus/src/rust/ficus_backend/src/grpc/kafka/streaming/t2/configs.rs @@ -11,20 +11,17 @@ pub enum T2StreamingConfiguration { impl T2StreamingConfiguration { pub fn new(grpc_config: &GrpcT2StreamingConfiguration) -> Option { - match grpc_config.configuration.as_ref() { - None => None, - Some(c) => Some(match c { - Configuration::LossyCount(lc) => T2StreamingConfiguration::LossyCount(LossyCountConfiguration { - error: lc.error, - support: lc.support, - trace_preprocessing_pipeline: grpc_config.incoming_traces_filtering_pipeline.clone(), - }), - Configuration::TimedSlidingWindow(sc) => T2StreamingConfiguration::SlidingWindow(TimedSlidingWindowConfiguration { - element_lifetime: Duration::from_millis(sc.lifespan_ms as u64), - trace_preprocessing_pipeline: grpc_config.incoming_traces_filtering_pipeline.clone(), - }), + grpc_config.configuration.as_ref().map(|c| match c { + Configuration::LossyCount(lc) => T2StreamingConfiguration::LossyCount(LossyCountConfiguration { + error: lc.error, + support: lc.support, + trace_preprocessing_pipeline: grpc_config.incoming_traces_filtering_pipeline.clone(), }), - } + Configuration::TimedSlidingWindow(sc) => T2StreamingConfiguration::SlidingWindow(TimedSlidingWindowConfiguration { + element_lifetime: Duration::from_millis(sc.lifespan_ms as u64), + trace_preprocessing_pipeline: grpc_config.incoming_traces_filtering_pipeline.clone(), + }), + }) } pub fn create_processor(&self) -> T2StreamingProcessor { diff --git a/Ficus/src/rust/ficus/src/grpc/kafka/streaming/t2/dfg_data_structures.rs b/Ficus/src/rust/ficus_backend/src/grpc/kafka/streaming/t2/dfg_data_structures.rs similarity index 95% rename from Ficus/src/rust/ficus/src/grpc/kafka/streaming/t2/dfg_data_structures.rs rename to Ficus/src/rust/ficus_backend/src/grpc/kafka/streaming/t2/dfg_data_structures.rs index 7f62448b6..3b0a13df1 100644 --- a/Ficus/src/rust/ficus/src/grpc/kafka/streaming/t2/dfg_data_structures.rs +++ b/Ficus/src/rust/ficus_backend/src/grpc/kafka/streaming/t2/dfg_data_structures.rs @@ -1,4 +1,9 @@ -use crate::{ +use crate::grpc::kafka::{ + models::XesFromBxesKafkaTraceCreatingError, + streaming::processors::{CaseMetadata, ProcessMetadata}, +}; +use bxes::models::domain::bxes_value::BxesValue; +use ficus::{ event_log::{ core::{event::event::Event, trace::trace::Trace}, xes::xes_trace::XesTraceImpl, @@ -11,14 +16,9 @@ use crate::{ sliding_window::SlidingWindow, }, }, - grpc::kafka::{ - models::XesFromBxesKafkaTraceCreatingError, - streaming::processors::{CaseMetadata, ProcessMetadata}, - }, pipelines::{context::PipelineContext, keys::context_keys::EVENT_LOG_INFO_KEY}, utils::user_data::user_data::UserData, }; -use bxes::models::domain::bxes_value::BxesValue; use log::{debug, warn}; use std::{cell::RefCell, collections::HashMap, hash::Hash, rc::Rc, time::Duration}; use uuid::Uuid; @@ -89,10 +89,11 @@ impl DfgDataStructureBase { } pub fn last_seen_event_class(&self, case_id: &Uuid) -> Option { - match self.traces_last_event_classes.borrow().get(case_id) { - None => None, - Some(value) => Some(value.value().unwrap().to_owned()), - } + self + .traces_last_event_classes + .borrow() + .get(case_id) + .map(|value| value.value().unwrap().to_owned()) } pub fn to_event_log_info(&self, process_name: &str) -> Option { diff --git a/Ficus/src/rust/ficus/src/grpc/kafka/streaming/t2/mod.rs b/Ficus/src/rust/ficus_backend/src/grpc/kafka/streaming/t2/mod.rs similarity index 100% rename from Ficus/src/rust/ficus/src/grpc/kafka/streaming/t2/mod.rs rename to Ficus/src/rust/ficus_backend/src/grpc/kafka/streaming/t2/mod.rs diff --git a/Ficus/src/rust/ficus/src/grpc/kafka/streaming/t2/processors.rs b/Ficus/src/rust/ficus_backend/src/grpc/kafka/streaming/t2/processors.rs similarity index 99% rename from Ficus/src/rust/ficus/src/grpc/kafka/streaming/t2/processors.rs rename to Ficus/src/rust/ficus_backend/src/grpc/kafka/streaming/t2/processors.rs index 4d34c8b36..423e70180 100644 --- a/Ficus/src/rust/ficus/src/grpc/kafka/streaming/t2/processors.rs +++ b/Ficus/src/rust/ficus_backend/src/grpc/kafka/streaming/t2/processors.rs @@ -1,5 +1,4 @@ use crate::{ - event_log::{bxes::bxes_to_xes_converter::read_bxes_events, core::event_log::EventLog, xes::xes_event_log::XesEventLogImpl}, ficus_proto::GrpcPipeline, grpc::{ kafka::{ @@ -8,6 +7,9 @@ use crate::{ }, pipeline_executor::ServicePipelineExecutionContext, }, +}; +use ficus::{ + event_log::{bxes::bxes_to_xes_converter::read_bxes_events, core::event_log::EventLog, xes::xes_event_log::XesEventLogImpl}, pipelines::{ context::{PipelineContext, PipelineInfrastructure}, keys::context_keys::EVENT_LOG_KEY, diff --git a/Ficus/src/rust/ficus/src/grpc/logs_handler.rs b/Ficus/src/rust/ficus_backend/src/grpc/logs_handler.rs similarity index 95% rename from Ficus/src/rust/ficus/src/grpc/logs_handler.rs rename to Ficus/src/rust/ficus_backend/src/grpc/logs_handler.rs index d815c77af..26ad56754 100644 --- a/Ficus/src/rust/ficus/src/grpc/logs_handler.rs +++ b/Ficus/src/rust/ficus_backend/src/grpc/logs_handler.rs @@ -1,4 +1,4 @@ -use crate::pipelines::{context::LogMessageHandler, errors::pipeline_errors::PipelinePartExecutionError}; +use ficus::pipelines::{context::LogMessageHandler, errors::pipeline_errors::PipelinePartExecutionError}; use log::info; use std::sync::Arc; diff --git a/Ficus/src/rust/ficus/src/grpc/mod.rs b/Ficus/src/rust/ficus_backend/src/grpc/mod.rs similarity index 90% rename from Ficus/src/rust/ficus/src/grpc/mod.rs rename to Ficus/src/rust/ficus_backend/src/grpc/mod.rs index 49a64e791..857e219ec 100644 --- a/Ficus/src/rust/ficus/src/grpc/mod.rs +++ b/Ficus/src/rust/ficus_backend/src/grpc/mod.rs @@ -3,6 +3,7 @@ pub mod context_values_service; pub mod converters; pub mod events; pub mod get_context_pipeline; +pub mod grpc_utils; pub mod kafka; pub mod logs_handler; pub mod pipeline_executor; diff --git a/Ficus/src/rust/ficus/src/grpc/pipeline_executor.rs b/Ficus/src/rust/ficus_backend/src/grpc/pipeline_executor.rs similarity index 95% rename from Ficus/src/rust/ficus/src/grpc/pipeline_executor.rs rename to Ficus/src/rust/ficus_backend/src/grpc/pipeline_executor.rs index eb23e07da..81afeff3e 100644 --- a/Ficus/src/rust/ficus/src/grpc/pipeline_executor.rs +++ b/Ficus/src/rust/ficus_backend/src/grpc/pipeline_executor.rs @@ -6,6 +6,8 @@ use crate::{ get_context_pipeline::GetContextValuePipelinePart, logs_handler::{ConsoleLogMessageHandler, DelegatingLogMessageHandler, GrpcLogMessageHandlerImpl}, }, +}; +use ficus::{ pipelines::{ context::{LogMessageHandler, PipelineContext, PipelineInfrastructure}, errors::pipeline_errors::PipelinePartExecutionError, @@ -61,7 +63,7 @@ impl<'a> ServicePipelineExecutionContext<'a> { } pub fn grpc_pipeline(&self) -> &GrpcPipeline { - &self.grpc_pipeline + self.grpc_pipeline } pub fn parts(&self) -> &PipelineParts { @@ -69,7 +71,7 @@ impl<'a> ServicePipelineExecutionContext<'a> { } pub fn context_values(&self) -> &Vec { - &self.context_values + self.context_values } pub fn log_message_handler(&self) -> Arc> { @@ -161,21 +163,21 @@ impl<'a> ServicePipelineExecutionContext<'a> { } fn find_default_part(&self, grpc_default_part: &GrpcPipelinePart) -> Option> { - let mut part_config = UserDataImpl::new(); + let mut part_config = UserDataImpl::default(); let grpc_config = &grpc_default_part.configuration.as_ref().unwrap(); for conf_value in &grpc_config.configuration_parameters { let key_name = conf_value.key.as_ref().unwrap().name.as_ref(); if let Some(key) = find_context_key(key_name) { let value = conf_value.value.as_ref().unwrap().context_value.as_ref().unwrap(); - put_into_user_data(key.key(), value, &mut part_config, &self); + put_into_user_data(key.key(), value, &mut part_config, self); } } - match self.parts().find_part(&grpc_default_part.name) { - Some(default_part) => Some(Box::new(default_part(Box::new(part_config)))), - None => None, - } + self + .parts() + .find_part(&grpc_default_part.name) + .map(|default_part| Box::new(default_part(Box::new(part_config)))) } pub(super) fn create_initial_context(&'a self) -> PipelineContext<'a> { diff --git a/Ficus/src/rust/ficus_backend/src/main.rs b/Ficus/src/rust/ficus_backend/src/main.rs index 39ba5c94b..b329e78d1 100644 --- a/Ficus/src/rust/ficus_backend/src/main.rs +++ b/Ficus/src/rust/ficus_backend/src/main.rs @@ -1,12 +1,24 @@ -use ficus::ficus_proto::grpc_context_values_service_server::GrpcContextValuesServiceServer; -use ficus::ficus_proto::grpc_kafka_service_server::GrpcKafkaServiceServer; -use ficus::grpc::context_values_service::{ContextValueService, GrpcContextValueService}; -use ficus::grpc::kafka::grpc_kafka_service::GrpcKafkaServiceImpl; -use ficus::{ficus_proto::grpc_backend_service_server::GrpcBackendServiceServer, grpc::backend_service::FicusService}; +use crate::{ + ficus_proto::{ + grpc_backend_service_server::GrpcBackendServiceServer, grpc_context_values_service_server::GrpcContextValuesServiceServer, + grpc_kafka_service_server::GrpcKafkaServiceServer, + }, + grpc::{ + backend_service::FicusService, + context_values_service::{ContextValueService, GrpcContextValueService}, + kafka::grpc_kafka_service::GrpcKafkaServiceImpl, + }, +}; use log::{info, LevelFilter}; use std::sync::Arc; use tonic::transport::Server; +pub mod ficus_proto { + tonic::include_proto!("ficus"); +} + +mod grpc; + #[tokio::main] async fn main() -> Result<(), Box> { colog::basic_builder().filter_level(LevelFilter::Info).init(); diff --git a/Salve/ClusteringUtils.cs b/util_projects/Salve/ClusteringUtils.cs similarity index 100% rename from Salve/ClusteringUtils.cs rename to util_projects/Salve/ClusteringUtils.cs diff --git a/Salve/Program.cs b/util_projects/Salve/Program.cs similarity index 100% rename from Salve/Program.cs rename to util_projects/Salve/Program.cs diff --git a/Salve/Rust/RustcLogsParser.EventIndex.cs b/util_projects/Salve/Rust/RustcLogsParser.EventIndex.cs similarity index 100% rename from Salve/Rust/RustcLogsParser.EventIndex.cs rename to util_projects/Salve/Rust/RustcLogsParser.EventIndex.cs diff --git a/Salve/Rust/RustcLogsParser.cs b/util_projects/Salve/Rust/RustcLogsParser.cs similarity index 100% rename from Salve/Rust/RustcLogsParser.cs rename to util_projects/Salve/Rust/RustcLogsParser.cs diff --git a/Salve/Salve.csproj b/util_projects/Salve/Salve.csproj similarity index 86% rename from Salve/Salve.csproj rename to util_projects/Salve/Salve.csproj index 5894bd42a..57f0a08f8 100644 --- a/Salve/Salve.csproj +++ b/util_projects/Salve/Salve.csproj @@ -14,7 +14,7 @@ - +