@@ -31,6 +31,25 @@ def get(self, req: Request) -> bool:
3131 def __repr__ (self ) -> str :
3232 pass
3333
34+ @abstractmethod
35+ def process_trace (self , reader , max_req = - 1 , max_sec = - 1 , start_time = - 1 , end_time = - 1 ):
36+ """Process a trace with this cache and return miss ratio.
37+
38+ This method processes trace data entirely on the C++ side to avoid
39+ data movement overhead between Python and C++.
40+
41+ Args:
42+ reader: The trace reader instance
43+ max_req: Maximum number of requests to process (-1 for no limit)
44+ max_sec: Maximum seconds to process (-1 for no limit)
45+ start_time: Start time filter (-1 for no filter)
46+ end_time: End time filter (-1 for no filter)
47+
48+ Returns:
49+ float: Miss ratio (0.0 to 1.0)
50+ """
51+ pass
52+
3453
3554class EvictionPolicy (EvictionPolicyBase ):
3655 """Base class for all eviction policies."""
@@ -44,9 +63,54 @@ def init_cache(self, cache_size: int, **kwargs) -> Cache:
4463 def get (self , req : Request ) -> bool :
4564 return self .cache .get (req )
4665
66+ def process_trace (self , reader , max_req = - 1 , max_sec = - 1 , start_time = - 1 , end_time = - 1 ):
67+ """Process a trace with this cache and return miss ratio.
68+
69+ This method processes trace data entirely on the C++ side to avoid
70+ data movement overhead between Python and C++.
71+
72+ Args:
73+ reader: The trace reader instance
74+ max_req: Maximum number of requests to process (-1 for no limit)
75+ max_sec: Maximum seconds to process (-1 for no limit)
76+ start_time: Start time filter (-1 for no filter)
77+ end_time: End time filter (-1 for no filter)
78+
79+ Returns:
80+ float: Miss ratio (0.0 to 1.0)
81+
82+ Example:
83+ >>> cache = LRU(1024*1024)
84+ >>> reader = open_trace("trace.csv", TraceType.CSV_TRACE)
85+ >>> miss_ratio = cache.process_trace(reader)
86+ >>> print(f"Miss ratio: {miss_ratio:.4f}")
87+ """
88+ from ._libcachesim import process_trace
89+ return process_trace (self .cache , reader , max_req , max_sec , start_time , end_time )
90+
4791 def __repr__ (self ):
4892 return f"{ self .__class__ .__name__ } (cache_size={ self .cache .cache_size } )"
4993
94+ @property
95+ def n_req (self ):
96+ """Number of requests processed."""
97+ return self .cache .n_req
98+
99+ @property
100+ def n_obj (self ):
101+ """Number of objects currently in cache."""
102+ return self .cache .n_obj
103+
104+ @property
105+ def occupied_byte (self ):
106+ """Number of bytes currently occupied in cache."""
107+ return self .cache .occupied_byte
108+
109+ @property
110+ def cache_size (self ):
111+ """Total cache size in bytes."""
112+ return self .cache .cache_size
113+
50114
51115class FIFO (EvictionPolicy ):
52116 """First In First Out replacement policy.
@@ -356,7 +420,7 @@ class PythonHookCachePolicy(EvictionPolicyBase):
356420 >>> hit = cache.get(req)
357421 """
358422 def __init__ (self , cache_size : int , cache_name : str = "PythonHookCache" ):
359- self .cache_size = cache_size
423+ self ._cache_size = cache_size
360424 self .cache_name = cache_name
361425 self .cache = PythonHookCache (cache_size , cache_name )
362426 self ._hooks_set = False
@@ -391,6 +455,38 @@ def get(self, req: Request) -> bool:
391455 raise RuntimeError ("Hooks must be set before using the cache. Call set_hooks() first." )
392456 return self .cache .get (req )
393457
458+ def process_trace (self , reader , max_req = - 1 , max_sec = - 1 , start_time = - 1 , end_time = - 1 ):
459+ """Process a trace with this cache and return miss ratio.
460+
461+ This method processes trace data entirely on the C++ side to avoid
462+ data movement overhead between Python and C++.
463+
464+ Args:
465+ reader: The trace reader instance
466+ max_req: Maximum number of requests to process (-1 for no limit)
467+ max_sec: Maximum seconds to process (-1 for no limit)
468+ start_time: Start time filter (-1 for no filter)
469+ end_time: End time filter (-1 for no filter)
470+
471+ Returns:
472+ float: Miss ratio (0.0 to 1.0)
473+
474+ Raises:
475+ RuntimeError: If hooks have not been set
476+
477+ Example:
478+ >>> cache = PythonHookCachePolicy(1024*1024)
479+ >>> cache.set_hooks(init_hook, hit_hook, miss_hook, eviction_hook, remove_hook)
480+ >>> reader = open_trace("trace.csv", TraceType.CSV_TRACE)
481+ >>> miss_ratio = cache.process_trace(reader)
482+ >>> print(f"Miss ratio: {miss_ratio:.4f}")
483+ """
484+ if not self ._hooks_set :
485+ raise RuntimeError ("Hooks must be set before processing trace. Call set_hooks() first." )
486+
487+ from ._libcachesim import process_trace_python_hook
488+ return process_trace_python_hook (self .cache , reader , max_req , max_sec , start_time , end_time )
489+
394490 @property
395491 def n_req (self ):
396492 """Number of requests processed."""
@@ -406,6 +502,11 @@ def occupied_byte(self):
406502 """Number of bytes currently occupied in cache."""
407503 return self .cache .occupied_byte
408504
505+ @property
506+ def cache_size (self ):
507+ """Total cache size in bytes."""
508+ return self .cache .cache_size
509+
409510 def __repr__ (self ):
410- return f"{ self .__class__ .__name__ } (cache_size={ self .cache_size } , " \
511+ return f"{ self .__class__ .__name__ } (cache_size={ self ._cache_size } , " \
411512 f"cache_name='{ self .cache_name } ', hooks_set={ self ._hooks_set } )"
0 commit comments