@@ -315,6 +315,7 @@ struct KnownCounters
315315 const char * name;
316316 unsigned type;
317317 unsigned code;
318+ unsigned scope = 0 ;
318319};
319320
320321#define TOTAL_COUNTERS 11
@@ -324,18 +325,21 @@ constexpr KnownCounters knownCounters[TOTAL_COUNTERS] = {
324325 {" RealTime" , CNT_TIMER, CNT_TIME_REAL},
325326 {" UserTime" , CNT_TIMER, CNT_TIME_USER},
326327 {" SystemTime" , CNT_TIMER, CNT_TIME_SYSTEM},
327- {" Fetches" , CNT_DB_INFO, isc_info_fetches},
328- {" Marks" , CNT_DB_INFO, isc_info_marks},
329- {" Reads" , CNT_DB_INFO, isc_info_reads},
330- {" Writes" , CNT_DB_INFO, isc_info_writes},
331- {" CurrentMemory" , CNT_DB_INFO, isc_info_current_memory},
332- {" MaxMemory" , CNT_DB_INFO, isc_info_max_memory},
328+ {" Fetches" , CNT_DB_INFO, isc_info_fetches, fb_info_counts_scope_att },
329+ {" Marks" , CNT_DB_INFO, isc_info_marks, fb_info_counts_scope_att },
330+ {" Reads" , CNT_DB_INFO, isc_info_reads, fb_info_counts_scope_att },
331+ {" Writes" , CNT_DB_INFO, isc_info_writes, fb_info_counts_scope_att },
332+ {" CurrentMemory" , CNT_DB_INFO, isc_info_current_memory, fb_info_counts_scope_db },
333+ {" MaxMemory" , CNT_DB_INFO, isc_info_max_memory, fb_info_counts_scope_db },
333334 {" Buffers" , CNT_DB_INFO, isc_info_num_buffers},
334335 {" PageSize" , CNT_DB_INFO, isc_info_page_size}
335336};
336337
337338} // anonymous namespace
338339
340+ static Firebird::IAttachment* lastAttachment = nullptr ;
341+ static bool scopeTagsSupported = false ;
342+
339343void Why::UtilInterface::getPerfCounters (Firebird::CheckStatusWrapper* status,
340344 Firebird::IAttachment* att, const char * countersSet, ISC_INT64* counters)
341345{
@@ -350,8 +354,35 @@ void Why::UtilInterface::getPerfCounters(Firebird::CheckStatusWrapper* status,
350354 constexpr const char * delim = " \t ,;" ;
351355 unsigned typeMask = 0 ;
352356 unsigned n = 0 ;
353- UCHAR info[TOTAL_COUNTERS]; // will never use all, but do not care about few bytes
357+ // We multiply by two because tags are in random order and we need to store their scope before process
358+ UCHAR info[TOTAL_COUNTERS * 2 ]; // will never use all, but do not care about few bytes
354359 UCHAR* pinfo = info;
360+ unsigned lastScope = 0 ;
361+
362+ if (lastAttachment != att)
363+ {
364+ lastAttachment = att;
365+ scopeTagsSupported = true ;
366+
367+ const UCHAR tags[] =
368+ {
369+ fb_info_counts_scope_att,
370+ fb_info_counts_scope_db,
371+ isc_info_end
372+ };
373+
374+ UCHAR buffer[BUFFER_TINY];
375+ att->getInfo (status, sizeof (tags), tags, sizeof (buffer), buffer);
376+
377+ for (UCHAR* p = buffer; *p != isc_info_end; p++)
378+ {
379+ if (*p == isc_info_error)
380+ {
381+ scopeTagsSupported = false ;
382+ break ;
383+ }
384+ }
385+ }
355386
356387#ifdef WIN_NT
357388#define strtok_r strtok_s
@@ -372,7 +403,14 @@ void Why::UtilInterface::getPerfCounters(Firebird::CheckStatusWrapper* status,
372403 typeMask |= knownCounters[i].type ;
373404
374405 if (knownCounters[i].type == CNT_DB_INFO)
375- *pinfo++ = knownCounters[i].code ;
406+ {
407+ const UCHAR tag = knownCounters[i].code ;
408+ const unsigned scope = knownCounters[i].scope ;
409+
410+ if (scopeTagsSupported && scope && lastScope != scope) *pinfo++ = lastScope = scope;
411+
412+ *pinfo++ = tag;
413+ }
376414
377415 goto found;
378416 }
@@ -442,6 +480,10 @@ found: ;
442480
443481 switch (ipb)
444482 {
483+ case fb_info_counts_scope_att:
484+ case fb_info_counts_scope_db:
485+ continue ;
486+
445487 case isc_info_reads:
446488 case isc_info_writes:
447489 case isc_info_marks:
0 commit comments