from analysis import util from . import Analyzer, LogSettings, Result, ResultStore def init_filter(settings: LogSettings, state: str) -> callable: # this implies OR for lists; AND for dicts if type(settings.sequences[state]) in (str, list): return lambda entry: entry[settings.type_field] in settings.sequences[state] else: return lambda entry: util.combinate(settings.sequences[state], entry) class LocomotionActionAnalyzer(Analyzer): """ calculate locomotion/action times and ratio Anything between LogEntryCache and CacheEnableAction is counted as ActionTime, the rest as LocomotionTime. """ __name__ = "LocomotionAction" def process(self, entry: dict) -> bool: self.last_timestamp = entry["timestamp"] if self.instance_start is None: self.instance_start = self.last_timestamp self.last = self.last_timestamp if self.cache_time is None: self.cache_time = self.last_timestamp offset = self.last_timestamp - self.cache_time if self.current_cache is None and self.filter_start(entry): if entry['cache'] is None: return False self.current_cache = entry['cache']['@id'] self.cache_time = self.last_timestamp self.locomotion.append(offset) self.last = None elif self.current_cache and self.filter_end(entry): self.actions.append(offset) self.cache_time = self.last_timestamp self.current_cache = None self.last = None def result(self, store: ResultStore) -> None: if self.last is not None: if self.current_cache is None: self.locomotion.append(self.last - self.cache_time) else: self.actions.append(self.last - self.cache_time) self.last = None locomotion = sum(self.locomotion) action = sum(self.actions) total = locomotion + action store.add(Result(type(self), { 'locomotion_sum': locomotion, 'action_sum': action, 'locomotion': self.locomotion, 'action': self.actions, 'duration': (self.last_timestamp - self.instance_start), 'locomotion_relative': locomotion / total, 'action_relative': action / total, 'locomotion_action_ratio': locomotion / action, })) def __init__(self, settings: LogSettings): super().__init__(settings) self.filter_start = init_filter(settings, "start") self.filter_end = init_filter(settings, "end") self.current_cache = None self.cache_time = None self.locomotion = [] self.actions = [] self.instance_start = None self.last_timestamp = None self.last = None class CacheSequenceAnalyzer(Analyzer): __name__ = "CacheSequence" def process(self, entry: dict) -> bool: if self.filter(entry): if entry['cache']: self.store.append((entry['timestamp'], entry['cache']['@id'])) else: self.store.append((entry['timestamp'], entry['cache'])) return False def result(self, store: ResultStore) -> None: store.add(Result(type(self), list(self.store))) def __init__(self, settings: LogSettings): super().__init__(settings) self.store = [] self.filter = init_filter(settings, "start")