4848 */
4949@ NotThreadSafe
5050public class PerformanceStatsImpl implements PerformanceStats {
51+ private static final String CALLS = "calls" ;
52+ private static final String CDATA = "CDATA" ;
53+ private static final String ELAPSED = "elapsed" ;
54+ private static final String NAME = "name" ;
55+ private static final String OPTIMIZATION_LEVEL = "optimization-level" ;
56+ private static final String QUERY = "query" ;
57+ private static final String SOURCE = "source" ;
58+ private static final String TYPE = "type" ;
5159
52- private static class IndexStats {
60+ private final Map <String , QueryStats > queries = new HashMap <>();
61+ private final Map <FunctionStats , FunctionStats > functions = new HashMap <>();
62+ private final Map <IndexStats , IndexStats > indexStats = new HashMap <>();
63+ private final Set <OptimizationStats > optimizations = new HashSet <>();
64+ private final Enabler enabler ;
65+
66+ private boolean enabled ;
5367
68+ public PerformanceStatsImpl (final boolean enabled ) {
69+ this (enabled , x -> x );
70+ }
71+
72+ public PerformanceStatsImpl (final boolean enabled , final Enabler enabler ) {
73+ this .enabled = enabled ;
74+ this .enabler = enabler ;
75+ }
76+
77+ private static class IndexStats {
5478 final String source ;
5579 final String indexType ;
5680 final int line ;
5781 final int column ;
5882 final IndexOptimizationLevel indexOptimizationLevel ;
83+
5984 int usageCount = 1 ;
6085 long executionTime = 0 ;
6186
@@ -95,13 +120,13 @@ public boolean equals(final Object obj) {
95120 }
96121
97122 private static class QueryStats {
98-
99123 final String source ;
124+
100125 long executionTime = 0 ;
101126 int callCount = 1 ;
102127
103128 QueryStats (final String source ) {
104- this .source = ( source != null ? source : "" ) ;
129+ this .source = source == null ? "" : source ;
105130 }
106131
107132 public static QueryStats copy (final QueryStats other ) {
@@ -162,36 +187,16 @@ public boolean equals(final Object obj) {
162187 }
163188
164189 @ ThreadSafe
165- private static class OptimizationStats {
166- final String source ;
167- final OptimizationType type ;
168- final int line ;
169- final int column ;
170-
190+ private record OptimizationStats (String source , OptimizationType type , int line , int column ) {
171191 OptimizationStats (final String source , final OptimizationType type , final int line , final int column ) {
172- this .source = source != null ? source : "" ;
192+ this .source = source == null ? "" : source ;
173193 this .type = type ;
174194 this .line = line ;
175195 this .column = column ;
176196 }
177-
178- @ Override
179- public int hashCode () {
180- return 32 * type .hashCode () + source .hashCode () + line + column ;
181- }
182-
183- @ Override
184- public boolean equals (final Object obj ) {
185- if (obj instanceof OptimizationStats other ) {
186- return source .equals (other .source ) && type == other .type &&
187- line == other .line && column == other .column ;
188- }
189- return false ;
190- }
191197 }
192198
193199 private static class CompareByTime implements Comparator <FunctionStats > {
194-
195200 @ Override
196201 public int compare (final FunctionStats o1 , final FunctionStats o2 ) {
197202 return Long .compare (o1 .executionTime , o2 .executionTime );
@@ -203,24 +208,6 @@ public interface Enabler {
203208 boolean enabled (final boolean enabled );
204209 }
205210
206- private final Map <String , QueryStats > queries = new HashMap <>();
207- private final Map <FunctionStats , FunctionStats > functions = new HashMap <>();
208- private final Map <IndexStats , IndexStats > indexStats = new HashMap <>();
209- private final Set <OptimizationStats > optimizations = new HashSet <>();
210-
211- private final Enabler enabler ;
212-
213- private boolean enabled = false ;
214-
215- public PerformanceStatsImpl (final boolean enabled ) {
216- this (enabled , x -> x );
217- }
218-
219- public PerformanceStatsImpl (final boolean enabled , final Enabler enabler ) {
220- this .enabled = enabled ;
221- this .enabler = enabler ;
222- }
223-
224211 @ Override
225212 public void setEnabled (final boolean enabled ) {
226213 this .enabled = enabled ;
@@ -363,48 +350,50 @@ private FunctionStats[] sort() {
363350
364351 @ Override
365352 public void serialize (final MemTreeBuilder builder ) {
366- builder .startElement (new QName (XML_ELEMENT_CALLS , XML_NAMESPACE , XML_PREFIX ), null );
367- if (isEnabled ()) {
368- final AttributesImpl attrs = new AttributesImpl ();
369- for (final QueryStats stats : queries .values ()) {
370- attrs .clear ();
371- attrs .addAttribute ("" , "source" , "source" , "CDATA" , stats .source );
372- attrs .addAttribute ("" , "elapsed" , "elapsed" , "CDATA" , Double .toString (stats .executionTime / 1000.0 ));
373- attrs .addAttribute ("" , "calls" , "calls" , "CDATA" , Integer .toString (stats .callCount ));
374- builder .startElement (new QName ("query" , XML_NAMESPACE , XML_PREFIX ), attrs );
375- builder .endElement ();
376- }
377- for (final FunctionStats stats : functions .values ()) {
378- attrs .clear ();
379- attrs .addAttribute ("" , "name" , "name" , "CDATA" , stats .qname .getStringValue ());
380- attrs .addAttribute ("" , "elapsed" , "elapsed" , "CDATA" , Double .toString (stats .executionTime / 1000.0 ));
381- attrs .addAttribute ("" , "calls" , "calls" , "CDATA" , Integer .toString (stats .callCount ));
382- if (stats .source != null ) {
383- attrs .addAttribute ("" , "source" , "source" , "CDATA" , stats .source );
384- }
385- builder .startElement (new QName ("function" , XML_NAMESPACE , XML_PREFIX ), attrs );
386- builder .endElement ();
387- }
388- for (final IndexStats stats : indexStats .values ()) {
389- attrs .clear ();
390- attrs .addAttribute ("" , "type" , "type" , "CDATA" , stats .indexType );
391- attrs .addAttribute ("" , "source" , "source" , "CDATA" , stats .source + " [" + stats .line + ":" +
392- stats .column + "]" );
393- attrs .addAttribute ("" , "elapsed" , "elapsed" , "CDATA" , Double .toString (stats .executionTime / 1000.0 ));
394- attrs .addAttribute ("" , "calls" , "calls" , "CDATA" , Integer .toString (stats .usageCount ));
395- attrs .addAttribute ("" , "optimization-level" , "optimization" , "CDATA" , stats .indexOptimizationLevel .name ());
396- builder .startElement (new QName ("index" , XML_NAMESPACE , XML_PREFIX ), attrs );
397- builder .endElement ();
353+ final AttributesImpl attrs = new AttributesImpl ();
354+
355+ builder .startElement (new QName (XML_ELEMENT_CALLS , XML_NAMESPACE , XML_PREFIX ), attrs );
356+ // query statistics
357+ for (final QueryStats stats : queries .values ()) {
358+ attrs .clear ();
359+ attrs .addAttribute ("" , SOURCE , SOURCE , CDATA , stats .source );
360+ attrs .addAttribute ("" , ELAPSED , ELAPSED , CDATA , Double .toString (stats .executionTime / 1000.0 ));
361+ attrs .addAttribute ("" , CALLS , CALLS , CDATA , Integer .toString (stats .callCount ));
362+ builder .startElement (new QName (QUERY , XML_NAMESPACE , XML_PREFIX ), attrs );
363+ builder .endElement ();
364+ }
365+ // function statistics
366+ for (final FunctionStats stats : functions .values ()) {
367+ attrs .clear ();
368+ attrs .addAttribute ("" , NAME , NAME , CDATA , stats .qname .getStringValue ());
369+ attrs .addAttribute ("" , ELAPSED , ELAPSED , CDATA , Double .toString (stats .executionTime / 1000.0 ));
370+ attrs .addAttribute ("" , CALLS , CALLS , CDATA , Integer .toString (stats .callCount ));
371+ if (!stats .source .isEmpty ()) {
372+ attrs .addAttribute ("" , SOURCE , SOURCE , CDATA , stats .source );
398373 }
399- for (final OptimizationStats stats : optimizations ) {
400- attrs .clear ();
401- attrs .addAttribute ("" , "type" , "type" , "CDATA" , stats .type .toString ());
402- if (stats .source != null ) {
403- attrs .addAttribute ("" , "source" , "source" , "CDATA" , stats .source + " [" + stats .line + ":" + stats .column + "]" );
404- }
405- builder .startElement (new QName ("optimization" , XML_NAMESPACE , XML_PREFIX ), attrs );
406- builder .endElement ();
374+ builder .startElement (new QName ("function" , XML_NAMESPACE , XML_PREFIX ), attrs );
375+ builder .endElement ();
376+ }
377+ // index statistics
378+ for (final IndexStats stats : indexStats .values ()) {
379+ attrs .clear ();
380+ attrs .addAttribute ("" , TYPE , TYPE , CDATA , stats .indexType );
381+ attrs .addAttribute ("" , SOURCE , SOURCE , CDATA , "%s [%s:%s]" .formatted (stats .source , stats .line , stats .column ));
382+ attrs .addAttribute ("" , ELAPSED , ELAPSED , CDATA , Double .toString (stats .executionTime / 1000.0 ));
383+ attrs .addAttribute ("" , CALLS , CALLS , CDATA , Integer .toString (stats .usageCount ));
384+ attrs .addAttribute ("" , OPTIMIZATION_LEVEL , OPTIMIZATION_LEVEL , CDATA , stats .indexOptimizationLevel .name ());
385+ builder .startElement (new QName ("index" , XML_NAMESPACE , XML_PREFIX ), attrs );
386+ builder .endElement ();
387+ }
388+ // optimization statistics
389+ for (final OptimizationStats stats : optimizations ) {
390+ attrs .clear ();
391+ attrs .addAttribute ("" , TYPE , TYPE , CDATA , stats .type .toString ());
392+ if (stats .source != null ) {
393+ attrs .addAttribute ("" , SOURCE , SOURCE , CDATA , "%s [%s:%s]" .formatted (stats .source , stats .line , stats .column ));
407394 }
395+ builder .startElement (new QName ("optimization" , XML_NAMESPACE , XML_PREFIX ), attrs );
396+ builder .endElement ();
408397 }
409398 builder .endElement ();
410399 }
0 commit comments