@@ -67,7 +67,37 @@ def get_summary(self) -> Dict[str, Any]:
6767 'by_type' : {}
6868 }
6969
70- # Walk through database to compute statistics
70+ # Fast path for SQLite backends
71+ if self .db and hasattr (self .db , 'conn' ):
72+ from ucis .cover_type_t import CoverTypeT
73+ from ucis .scope_type_t import ScopeTypeT
74+ try :
75+ conn = self .db .conn
76+ summary ['covergroups' ] = conn .execute (
77+ "SELECT COUNT(*) FROM scopes WHERE (scope_type & ?) != 0" ,
78+ (int (ScopeTypeT .COVERGROUP ),)
79+ ).fetchone ()[0 ]
80+ summary ['coverpoints' ] = conn .execute (
81+ "SELECT COUNT(*) FROM scopes WHERE (scope_type & ?) != 0" ,
82+ (int (ScopeTypeT .COVERPOINT ),)
83+ ).fetchone ()[0 ]
84+ row = conn .execute (
85+ """SELECT COUNT(*),
86+ SUM(CASE WHEN cover_data > 0 THEN 1 ELSE 0 END)
87+ FROM coveritems
88+ WHERE (cover_type & ?) != 0""" ,
89+ (int (CoverTypeT .CVGBIN ),)
90+ ).fetchone ()
91+ summary ['total_bins' ] = row [0 ] or 0
92+ summary ['covered_bins' ] = row [1 ] or 0
93+ if summary ['total_bins' ] > 0 :
94+ summary ['overall_coverage' ] = (summary ['covered_bins' ] / summary ['total_bins' ]) * 100
95+ self ._cache ['summary' ] = summary
96+ return summary
97+ except Exception :
98+ pass
99+
100+ # Walk through database to compute statistics (fallback)
71101 def visit_scope (scope , depth = 0 ):
72102 from ucis .scope_type_t import ScopeTypeT
73103 from ucis .cover_type_t import CoverTypeT
@@ -125,8 +155,15 @@ def get_database_info(self) -> Dict[str, Any]:
125155 # Get test data if available
126156 if self .db :
127157 try :
128- tests = self .get_all_tests ()
129- info ['test_count' ] = len (tests )
158+ if hasattr (self .db , 'conn' ):
159+ from ucis .history_node_kind import HistoryNodeKind
160+ info ['test_count' ] = self .db .conn .execute (
161+ "SELECT COUNT(*) FROM history_nodes WHERE history_kind = ?" ,
162+ (int (HistoryNodeKind .TEST ),)
163+ ).fetchone ()[0 ]
164+ else :
165+ tests = self .get_all_tests ()
166+ info ['test_count' ] = len (tests )
130167 except :
131168 pass
132169
@@ -147,6 +184,25 @@ def get_coverage_types(self) -> List[CoverTypeT]:
147184 """
148185 if 'coverage_types' in self ._cache :
149186 return self ._cache ['coverage_types' ]
187+
188+ # Fast path for SQLite backend
189+ if self .db and hasattr (self .db , 'conn' ):
190+ try :
191+ rows = self .db .conn .execute (
192+ "SELECT DISTINCT cover_type FROM coveritems ORDER BY cover_type"
193+ ).fetchall ()
194+ types_list = []
195+ for r in rows :
196+ if r [0 ] is None :
197+ continue
198+ try :
199+ types_list .append (CoverTypeT (r [0 ]))
200+ except Exception :
201+ pass
202+ self ._cache ['coverage_types' ] = types_list
203+ return types_list
204+ except Exception :
205+ pass
150206
151207 types_found : Set [CoverTypeT ] = set ()
152208
@@ -206,6 +262,30 @@ def get_code_coverage_summary(self) -> Dict[str, Any]:
206262 CoverTypeT .FSMBIN : 'fsm' ,
207263 CoverTypeT .BLOCKBIN : 'block' ,
208264 }
265+
266+ # Fast path for SQLite backend
267+ if self .db and hasattr (self .db , 'conn' ):
268+ try :
269+ rows = self .db .conn .execute (
270+ """SELECT cover_type,
271+ COUNT(*) AS total,
272+ SUM(CASE WHEN cover_data > 0 THEN 1 ELSE 0 END) AS covered
273+ FROM coveritems
274+ GROUP BY cover_type"""
275+ ).fetchall ()
276+ int_type_map = {int (k ): v for k , v in type_map .items ()}
277+ for row in rows :
278+ key = int_type_map .get (row [0 ])
279+ if key is not None :
280+ summary [key ]['total' ] = row [1 ] or 0
281+ summary [key ]['covered' ] = row [2 ] or 0
282+ for key in summary :
283+ if summary [key ]['total' ] > 0 :
284+ summary [key ]['coverage' ] = (summary [key ]['covered' ] / summary [key ]['total' ]) * 100
285+ self ._cache ['code_coverage_summary' ] = summary
286+ return summary
287+ except Exception :
288+ pass
209289
210290 def visit_scope (scope ):
211291 for cov_type , key in type_map .items ():
@@ -268,6 +348,37 @@ def get_coverage_by_type(self, cov_type: CoverTypeT, filtered: bool = True) -> D
268348 'covered' : 0 ,
269349 'coverage' : 0.0
270350 }
351+
352+ # Fast path for SQLite backend
353+ if self .db and hasattr (self .db , 'conn' ):
354+ try :
355+ if filter_active :
356+ row = self .db .conn .execute (
357+ """SELECT COUNT(*),
358+ SUM(CASE WHEN ci.cover_data > 0 THEN 1 ELSE 0 END)
359+ FROM coveritems ci
360+ JOIN coveritem_tests ct ON ct.cover_id = ci.cover_id
361+ JOIN history_nodes hn ON hn.history_id = ct.history_id
362+ WHERE (ci.cover_type & ?) != 0
363+ AND hn.logical_name = ?""" ,
364+ (int (cov_type ), self .test_filter )
365+ ).fetchone ()
366+ else :
367+ row = self .db .conn .execute (
368+ """SELECT COUNT(*),
369+ SUM(CASE WHEN cover_data > 0 THEN 1 ELSE 0 END)
370+ FROM coveritems
371+ WHERE (cover_type & ?) != 0""" ,
372+ (int (cov_type ),)
373+ ).fetchone ()
374+ result ['total' ] = row [0 ] or 0
375+ result ['covered' ] = row [1 ] or 0
376+ if result ['total' ] > 0 :
377+ result ['coverage' ] = (result ['covered' ] / result ['total' ]) * 100
378+ self ._cache [cache_key ] = result
379+ return result
380+ except Exception :
381+ pass
271382
272383 def visit_scope (scope ):
273384 try :
0 commit comments