One sampling record of latency data. Holds frequency & intensity histograms (buckets in log2 indices).
| 140 | # --------------------------- Data types & helpers --------------------------- # |
| 141 | |
| 142 | class LatencyRecord: |
| 143 | """ |
| 144 | One sampling record of latency data. |
| 145 | Holds frequency & intensity histograms (buckets in log2 indices). |
| 146 | """ |
| 147 | def __init__(self) -> None: |
| 148 | # Raw data: exponent-> cumulative count at timestamp. Special keys: 'timestamp' |
| 149 | self.data: Dict[int | str, int] = {} |
| 150 | |
| 151 | # Pre-allocate with a generous upper bound; safe even after autotune shrinks the range. |
| 152 | self.frequency_histogram: List[float] = [0.0 for _ in range(0, 65)] |
| 153 | self.intensity_histogram: List[float] = [0.0 for _ in range(0, 65)] |
| 154 | |
| 155 | self.delta_time: int = 0 # microseconds between this and previous record |
| 156 | self.max_frequency: float = 0.0 |
| 157 | self.sum_frequency: float = 0.0 |
| 158 | self.max_intensity: float = 0.0 |
| 159 | self.sum_intensity: float = 0.0 |
| 160 | self.date: str = '' |
| 161 | self.label: str = '' |
| 162 | self.data_source: str = g_params.default_data_source |
| 163 | |
| 164 | # ---------------------- Input parsing & record IO ---------------------- # |
| 165 | |
| 166 | @staticmethod |
| 167 | def _read_non_empty_line_lower_stripped() -> str: |
| 168 | while True: |
| 169 | line = sys.stdin.readline() |
| 170 | if not line: |
| 171 | print("\nReached EOF from data source, exiting.") |
| 172 | sys.exit(0) |
| 173 | line = line.strip() |
| 174 | if line: |
| 175 | return line.lower() |
| 176 | |
| 177 | def go_to_begin_record_tag(self) -> None: |
| 178 | while True: |
| 179 | if self._read_non_empty_line_lower_stripped() == g_params.begin_tag: |
| 180 | return |
| 181 | |
| 182 | def read_record(self) -> None: |
| 183 | while True: |
| 184 | line = self._read_non_empty_line_lower_stripped() |
| 185 | split_line = [x.strip() for x in line.split(",")] |
| 186 | |
| 187 | # End-of-record |
| 188 | if len(split_line) == 1 and split_line[0] == g_params.end_tag: |
| 189 | return |
| 190 | |
| 191 | # Header / meta lines |
| 192 | if len(split_line) == 4 and split_line[0] == 'timestamp' and split_line[1] == 'microsec': |
| 193 | self.data['timestamp'] = int(split_line[2]) |
| 194 | self.date = split_line[3] |
| 195 | continue |
| 196 | |
| 197 | if len(split_line) == 2 and split_line[0] == g_params.label_tag: |
| 198 | self.label = split_line[1] |
| 199 | continue |