88from typing import Iterator
99import numpy as np
1010import pandas as pd
11+ import gc
1112
1213CSV_COLUMN_TYPES = {
1314 "START_TIME" : np .uint64 ,
1415 "END_TIME" : np .uint64 ,
15- "PROTOCOL" : np .uint8 ,
16- "SRC_IP" : str ,
17- "DST_IP" : str ,
18- "SRC_PORT" : np .uint16 ,
19- "DST_PORT" : np .uint16 ,
16+ # "PROTOCOL": np.uint8,
17+ # "SRC_IP": str,
18+ # "DST_IP": str,
19+ # "SRC_PORT": np.uint16,
20+ # "DST_PORT": np.uint16,
2021 "PACKETS" : np .uint64 ,
2122 "BYTES" : np .uint64 ,
2223 "EXPORT_TIME" : np .uint64 ,
3435
3536STATS_CSV_COLUMN_TYPES = {
3637 "Time" : np .uint64 ,
37- "UID" : np .uint64 ,
38- "PID" : np .uint64 ,
39- "percent_usr" : np .float64 ,
40- "percent_system" : np .float64 ,
41- "percent_guest" : np .float64 ,
42- "percent_wait" : np .float64 ,
38+ # "UID": np.uint64,
39+ # "PID": np.uint64,
40+ # "percent_usr": np.float64,
41+ # "percent_system": np.float64,
42+ # "percent_guest": np.float64,
43+ # "percent_wait": np.float64,
4344 "percent_CPU" : np .float64 ,
44- "CPU" : np .uint64 ,
45- "minflt/s" : np .float64 ,
46- "majflt/s" : np .float64 ,
47- "VSZ" : np .uint64 ,
48- "RSS" : np .uint64 ,
45+ # "CPU": np.uint64,
46+ # "minflt/s": np.float64,
47+ # "majflt/s": np.float64,
48+ # "VSZ": np.uint64,
49+ # "RSS": np.uint64,
4950 "percent_MEM" : np .float64 ,
50- "StkSize" : np .uint64 ,
51- "StkRef" : np .uint64 ,
52- "threads" : np .uint64 ,
53- "fd-nr" : np .uint64 ,
54- "Command" : str ,
51+ # "StkSize": np.uint64,
52+ # "StkRef": np.uint64,
53+ # "threads": np.uint64,
54+ # "fd-nr": np.uint64,
55+ # "Command": str,
5556}
5657
5758SUM_PIDSTAT_COLS = [
58- "percent_usr" ,
59- "percent_system" ,
60- "percent_guest" ,
61- "percent_wait" ,
59+ # "percent_usr",
60+ # "percent_system",
61+ # "percent_guest",
62+ # "percent_wait",
6263 "percent_CPU" ,
63- "minflt/s" ,
64- "majflt/s" ,
65- "fd-nr" ,
64+ # "minflt/s",
65+ # "majflt/s",
66+ # "fd-nr",
6667]
6768TAKE_PIDSTAT_COLS = [
68- "RSS" ,
69- "VSZ" ,
69+ # "RSS",
70+ # "VSZ",
7071 "percent_MEM" ,
71- "threads" ,
72- "UID" ,
73- "Command" ,
74- "CPU" ,
72+ # "threads",
73+ # "UID",
74+ # "Command",
75+ # "CPU",
7576 "Time" ,
7677]
7778
@@ -166,7 +167,7 @@ def __init__(self, row):
166167
167168
168169def create_event_queue (
169- flows_csv_path : os .PathLike , hosts_stats_file : os .PathLike , out_dir : str = None
170+ flows_path : os .PathLike , hosts_stats_file : os .PathLike , out_dir : str = None
170171) -> Iterator [Event ]:
171172 if not out_dir :
172173 out_dir = tempfile .mkdtemp (prefix = "flows_split_" )
@@ -184,15 +185,19 @@ def create_event_queue(
184185 sorted_by_export_path = os .path .join (out_dir , "flows_sorted_by_export.csv" )
185186
186187 # Load and split
187- df = pd .read_csv (flows_csv_path , dtype = CSV_COLUMN_TYPES )
188- df .fillna (0 )
188+ df = pd .read_csv (
189+ flows_path ,
190+ dtype = CSV_COLUMN_TYPES ,
191+ usecols = CSV_COLUMN_TYPES .keys (),
192+ engine = "pyarrow" ,
193+ )
189194
190195 # Filer host stats file by time
191196 start = math .floor (df ["START_TIME" ].min () / 1000 )
192197 end = math .ceil (df ["END_TIME" ].max () / 1000 )
193198
194199 stats_df : pd .DataFrame = pd .read_csv (
195- hosts_stats_file , sep = ";" , dtype = STATS_CSV_COLUMN_TYPES
200+ hosts_stats_file , sep = ";" , dtype = STATS_CSV_COLUMN_TYPES , engine = "pyarrow"
196201 )
197202 stats_df = stats_df [(stats_df ["Time" ] >= start ) & (stats_df ["Time" ] <= end )]
198203
@@ -216,15 +221,6 @@ def create_event_queue(
216221 .to_csv (one_packet_path , index = False )
217222 )
218223
219- # Multi-packet flows
220- multi_df = (
221- df [df ["PACKETS" ] > 1 ]
222- .groupby (["START_TIME" , "END_TIME" ], as_index = False )
223- .agg (** agg_dict )
224- )
225- multi_df .sort_values ("START_TIME" ).to_csv (sorted_by_start_path , index = False )
226- multi_df .sort_values ("END_TIME" ).to_csv (sorted_by_end_path , index = False )
227-
228224 # Export Events
229225 if "EXPORT_TIME" in df .columns :
230226 df .groupby (["EXPORT_TIME" , "SEQ_NUMBER" ], as_index = False ).agg (
@@ -235,6 +231,20 @@ def create_event_queue(
235231 with open (sorted_by_export_path , "w+" ) as f :
236232 f .write ("EXPORT_TIME,SEQ_NUMBER,FLOWS,MSG_LENGTH" )
237233
234+ # Multi-packet flows
235+ multi_df = (
236+ df [df ["PACKETS" ] > 1 ]
237+ .groupby (["START_TIME" , "END_TIME" ], as_index = False )
238+ .agg (** agg_dict )
239+ )
240+ del df
241+ gc .collect ()
242+ multi_df .sort_values ("START_TIME" ).to_csv (sorted_by_start_path , index = False )
243+ gc .collect ()
244+ multi_df .sort_values ("END_TIME" ).to_csv (sorted_by_end_path , index = False )
245+ del multi_df
246+ gc .collect ()
247+
238248 return heapq .merge (
239249 read_one_packet_events (one_packet_path ),
240250 read_start_events (sorted_by_start_path ),
@@ -254,6 +264,7 @@ def read_export_events(path: os.PathLike):
254264 "FLOWS" : np .uint64 ,
255265 "MSG_LENGTH" : np .uint64 ,
256266 },
267+ usecols = ["EXPORT_TIME" , "SEQ_NUMBER" , "FLOWS" , "MSG_LENGTH" ],
257268 chunksize = 100_000 ,
258269 ):
259270 for row in chunk .itertuples (index = False ):
@@ -266,7 +277,11 @@ def read_export_events(path: os.PathLike):
266277
267278def read_host_stats_events (path : os .PathLike ):
268279 for chunk in pd .read_csv (
269- path , chunksize = 100_000 , sep = ";" , dtype = STATS_CSV_COLUMN_TYPES
280+ path ,
281+ chunksize = 100_000 ,
282+ sep = ";" ,
283+ dtype = STATS_CSV_COLUMN_TYPES ,
284+ usecols = STATS_CSV_COLUMN_TYPES .keys (),
270285 ):
271286 for row in chunk .itertuples (index = False ):
272287 yield HostStatsEvent (row )
@@ -276,7 +291,12 @@ def read_one_packet_events(path: str) -> Iterator[OnePacketFlow]:
276291 CSV_AGGREGATE_TYPES_NO_END = {
277292 k : v for k , v in CSV_AGGREGATE_TYPES .items () if k != "END_TIME"
278293 }
279- for chunk in pd .read_csv (path , dtype = CSV_AGGREGATE_TYPES_NO_END , chunksize = 100_000 ):
294+ for chunk in pd .read_csv (
295+ path ,
296+ dtype = CSV_AGGREGATE_TYPES_NO_END ,
297+ chunksize = 100_000 ,
298+ usecols = CSV_AGGREGATE_TYPES_NO_END .keys (),
299+ ):
280300 for row in chunk .itertuples (index = False ):
281301 yield OnePacketFlow (
282302 bytes = np .uint64 (row .BYTES ),
@@ -287,7 +307,12 @@ def read_one_packet_events(path: str) -> Iterator[OnePacketFlow]:
287307
288308
289309def read_start_events (path : str ) -> Iterator [FlowStartEvent ]:
290- for chunk in pd .read_csv (path , dtype = CSV_AGGREGATE_TYPES , chunksize = 100_000 ):
310+ for chunk in pd .read_csv (
311+ path ,
312+ dtype = CSV_AGGREGATE_TYPES ,
313+ chunksize = 100_000 ,
314+ usecols = CSV_AGGREGATE_TYPES .keys (),
315+ ):
291316 durations = (chunk .END_TIME - chunk .START_TIME + 1 ) / 1_000
292317 data_rates = (chunk .BYTES * 8 ) / durations
293318 packet_rates = chunk .PACKETS / durations
@@ -305,7 +330,12 @@ def read_start_events(path: str) -> Iterator[FlowStartEvent]:
305330
306331
307332def read_end_events (path : str ) -> Iterator [FlowEndEvent ]:
308- for chunk in pd .read_csv (path , dtype = CSV_AGGREGATE_TYPES , chunksize = 100_000 ):
333+ for chunk in pd .read_csv (
334+ path ,
335+ dtype = CSV_AGGREGATE_TYPES ,
336+ chunksize = 100_000 ,
337+ usecols = CSV_AGGREGATE_TYPES .keys (),
338+ ):
309339 durations = (chunk .END_TIME - chunk .START_TIME + 1 ) / 1_000
310340 data_rates = (chunk .BYTES * 8 ) / durations
311341 packet_rates = chunk .PACKETS / durations
0 commit comments