1
/* Copyright (C) 2005 PrimeBase Technologies GmbH
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
* 2005-01-03 Paul McCullagh
24
#include "xt_config.h"
30
#include "strutil_xt.h"
32
xtPublic void xt_strcpy(size_t size, char *to, c_char *from)
36
while (*from && size--)
42
xtPublic void xt_strncpy(size_t size, char *to, c_char *from, size_t len_from)
46
while (len_from-- && size--)
52
xtPublic void xt_strcpy_term(size_t size, char *to, c_char *from, char term)
56
while (*from && *from != term && size--)
62
xtPublic void xt_strcat_term(size_t size, char *to, c_char *from, char term)
64
while (*to && size--) to++;
67
while (*from && *from != term && size--)
73
xtPublic void xt_strcat(size_t size, char *to, c_char *from)
75
while (*to && size--) to++;
76
xt_strcpy(size, to, from);
79
xtPublic void xt_strcati(size_t size, char *to, int i)
83
sprintf(buffer, "%d", i);
84
xt_strcat(size, to, buffer);
87
xtPublic xtBool xt_ends_with(c_char *str, c_char *sub)
89
unsigned long len = strlen(str);
91
if (len >= strlen(sub))
92
return strcmp(&str[len-strlen(sub)], sub) == 0;
96
xtPublic xtPublic xtBool xt_starts_with(c_char *str, c_char *sub)
98
return (strstr(str, sub) == str);
101
/* This function returns "" if the path ends with a dir char */
102
xtPublic void xt_2nd_last_name_of_path(size_t size, char *dest, c_char *path)
113
/* {INVALID-OLD-TABLE-FIX}
114
* I have changed the implementation of
115
* this bug fix (see {INVALID-OLD-TABLE-FIX}).
116
if (!is_prefix(path, mysql_data_home) &&
117
!is_prefix(path, mysql_real_data_home))
124
ptr = path + len - 1;
125
while (ptr != path && !XT_IS_DIR_CHAR(*ptr))
127
if (!XT_IS_DIR_CHAR(*ptr)) {
133
while (ptr != path && !XT_IS_DIR_CHAR(*ptr))
135
if (XT_IS_DIR_CHAR(*ptr))
137
len = (size_t) (pend - ptr);
140
memcpy(dest, ptr, len);
144
/* This function returns "" if the path ends with a dir char */
145
xtPublic char *xt_last_name_of_path(c_char *path)
150
length = strlen(path);
152
return (char *) path;
153
ptr = path + length - 1;
154
while (ptr != path && !XT_IS_DIR_CHAR(*ptr)) ptr--;
155
if (XT_IS_DIR_CHAR(*ptr)) ptr++;
159
xtPublic char *xt_last_2_names_of_path(c_char *path)
164
length = strlen(path);
166
return (char *) path;
167
ptr = path + length - 1;
168
while (ptr != path && !XT_IS_DIR_CHAR(*ptr)) ptr--;
169
if (XT_IS_DIR_CHAR(*ptr)) {
171
while (ptr != path && !XT_IS_DIR_CHAR(*ptr)) ptr--;
172
if (XT_IS_DIR_CHAR(*ptr))
178
xtPublic c_char *xt_last_directory_of_path(c_char *path)
179
/* This function returns the last name component, even if the path ends with a dir char */
184
length = strlen(path);
187
ptr = path + length - 1;
188
/* Path may end with multiple slashes: */
189
while (ptr != path && XT_IS_DIR_CHAR(*ptr))
191
while (ptr != path && !XT_IS_DIR_CHAR(*ptr))
193
if (XT_IS_DIR_CHAR(*ptr)) ptr++;
197
xtPublic char *xt_find_extension(c_char *file_name)
201
for (ptr = file_name + strlen(file_name) - 1; ptr >= file_name; ptr--) {
202
if (XT_IS_DIR_CHAR(*ptr))
205
return (char *) (ptr + 1);
210
xtPublic void xt_remove_extension(char *file_name)
212
char *ptr = xt_find_extension(file_name);
218
xtPublic xtBool xt_is_extension(c_char *file_name, c_char *ext)
222
if (!(ptr = xt_find_extension(file_name)))
224
return strcmp(ptr, ext) == 0;
228
* Optionally remove trailing directory delimiters (If the directory name consists of one
229
* character, the directory delimiter is not removed).
231
xtPublic xtBool xt_remove_dir_char(char *dir_name)
234
xtBool removed = FALSE;
236
length = strlen(dir_name);
237
while (length > 1 && XT_IS_DIR_CHAR(dir_name[length - 1])) {
238
dir_name[length - 1] = '\0';
245
xtPublic void xt_remove_last_name_of_path(char *path)
249
if ((ptr = xt_last_name_of_path(path)))
253
xtBool xt_add_dir_char(size_t max, char *path)
255
size_t slen = strlen(path);
261
/* If no path is given we will be at the current working directory, under UNIX we must
262
* NOT add a directory delimiter character:
267
if (!XT_IS_DIR_CHAR(path[slen - 1])) {
268
path[slen] = XT_DIR_CHAR;
269
path[slen + 1] = '\0';
275
xtPublic xtInt8 xt_str_to_int8(c_char *ptr, xtBool *overflow)
281
while (*ptr == '0') ptr++;
285
sscanf(ptr, "%"PRId64, &value);
286
if (!value && overflow)
292
xtPublic void xt_int8_to_str(xtInt8 value, char *string)
294
sprintf(string, "%"PRId64, value);
297
xtPublic void xt_double_to_str(double value, int scale, char *string)
301
sprintf(string, "%.*f", scale, value);
302
ptr = string + strlen(string) - 1;
304
if (strchr(string, '.') && (*ptr == '0' || *ptr == '.')) {
305
while (ptr-1 > string && *(ptr-1) == '0') ptr--;
306
if (ptr-1 > string && *(ptr-1) == '.') ptr--;
312
* This function understand GB, MB, KB.
314
xtPublic xtInt8 xt_byte_size_to_int8(c_char *ptr)
316
char number[101], *num_ptr;
319
while (*ptr && isspace(*ptr))
323
while (*ptr && isdigit(*ptr)) {
324
if (num_ptr < number+100) {
331
size = xt_str_to_int8(number, NULL);
333
while (*ptr && isspace(*ptr))
336
switch (toupper(*ptr)) {
353
xtPublic void xt_int8_to_byte_size(xtInt8 value, char *string)
359
if (value >= (xtInt8) (1024 * 1024 * 1024)) {
360
v = (double) value / (double) (1024 * 1024 * 1024);
363
else if (value >= (xtInt8) (1024 * 1024)) {
364
v = (double) value / (double) (1024 * 1024);
367
else if (value >= (xtInt8) 1024) {
368
v = (double) value / (double) (1024);
376
xt_double_to_str(v, 2, val_str);
377
sprintf(string, "%s %s (%"PRId64" bytes)", val_str, unit, value);
380
/* Version number must also be set in configure.in! */
381
xtPublic c_char *xt_get_version(void)
386
/* Copy and URL decode! */
387
xtPublic void xt_strcpy_url(size_t size, char *to, c_char *from)
391
while (*from && size--) {
392
if (*from == '%' && isxdigit(*(from+1)) && isxdigit(*(from+2))) {
393
unsigned char a = xt_hex_digit(*(from+1));
394
unsigned char b = xt_hex_digit(*(from+2));
405
/* Copy and URL decode! */
406
xtPublic void xt_strncpy_url(size_t size, char *to, c_char *from, size_t len_from)
410
while (len_from-- && size--) {
411
if (*from == '%' && len_from >= 2 && isxdigit(*(from+1)) && isxdigit(*(from+2))) {
412
unsigned char a = xt_hex_digit(*(from+1));
413
unsigned char b = xt_hex_digit(*(from+2));
424
/* Returns a pointer to the end of the string if nothing found! */
425
const char *xt_strchr(const char *str, char ch)
427
while (*str && *str != ch) str++;
431
unsigned char xt_hex_digit(char ch)
434
return((unsigned char) ch - (unsigned char) '0');
437
if (ch >= 'A' && ch <= 'F')
438
return((unsigned char) ch - (unsigned char) 'A' + (unsigned char) 10);
440
return((unsigned char) 0);
444
xtPublic void xt_win_dialog(char *message)
446
MessageBoxA(NULL, message, "Debug Me!", MB_ICONWARNING | MB_OK);
451
* --------------- SYSTEM STATISTICS ------------------
454
static char su_t_unit[10] = "usec";
456
* Note times, are return in microseconds, but the display in xtstat is currently
459
static XTStatMetaDataRec pbxt_stat_meta_data[XT_STAT_MAXIMUM] = {
460
{ XT_STAT_TIME_CURRENT, "Current Time", "time", "curr", XT_STAT_DATE,
461
"The current time in seconds" },
462
{ XT_STAT_TIME_PASSED, "Time Since Last Call", "time", su_t_unit, XT_STAT_ACCUMULATIVE | XT_STAT_TIME_VALUE,
463
"Time passed in %sseconds since last statistics call" },
465
{ XT_STAT_COMMITS, "Commit Count", "xact", "commt", XT_STAT_ACCUMULATIVE,
466
"Number of transactions committed" },
467
{ XT_STAT_ROLLBACKS, "Rollback Count", "xact", "rollb", XT_STAT_ACCUMULATIVE,
468
"Number of transactions rolled back" },
469
{ XT_STAT_WAIT_FOR_XACT, "Wait for Xact Count", "xact", "waits", XT_STAT_ACCUMULATIVE,
470
"Number of times waited for another transaction" },
471
{ XT_STAT_XACT_TO_CLEAN, "Dirty Xact Count", "xact", "dirty", 0,
472
"Number of transactions still to be cleaned up" },
474
{ XT_STAT_STAT_READS, "Read Statements", "stat", "read", XT_STAT_ACCUMULATIVE,
475
"Number of SELECT statements" },
476
{ XT_STAT_STAT_WRITES, "Write Statements", "stat", "write", XT_STAT_ACCUMULATIVE,
477
"Number of UPDATE/INSERT/DELETE statements" },
479
{ XT_STAT_REC_BYTES_IN, "Record Bytes Read", "rec", "in", XT_STAT_ACCUMULATIVE | XT_STAT_BYTE_COUNT,
480
"Bytes read from the record/row files" },
481
{ XT_STAT_REC_BYTES_OUT, "Record Bytes Written", "rec", "out", XT_STAT_ACCUMULATIVE | XT_STAT_BYTE_COUNT,
482
"Bytes written from the record/row files" },
483
{ XT_STAT_REC_SYNC_COUNT, "Record File Flushes", "rec", "syncs", XT_STAT_ACCUMULATIVE | XT_STAT_COMBO_FIELD,
484
"Number of flushes to record/row files" },
485
{ XT_STAT_REC_SYNC_TIME, "Record Flush Time", "rec", su_t_unit, XT_STAT_ACCUMULATIVE | XT_STAT_TIME_VALUE | XT_STAT_COMBO_FIELD_2,
486
"The time in %sseconds to flush record/row files" },
487
{ XT_STAT_REC_CACHE_HIT, "Record Cache Hits", "rec", "hits", XT_STAT_ACCUMULATIVE,
488
"Hits when accessing the record cache" },
489
{ XT_STAT_REC_CACHE_MISS, "Record Cache Misses", "rec", "miss", XT_STAT_ACCUMULATIVE,
490
"Misses when accessing the record cache" },
491
{ XT_STAT_REC_CACHE_FREES, "Record Cache Frees", "rec", "frees", XT_STAT_ACCUMULATIVE,
492
"Number of record cache pages freed" },
493
{ XT_STAT_REC_CACHE_USAGE, "Record Cache Usage", "rec", "%use", XT_STAT_PERCENTAGE,
494
"Percentage of record cache in use" },
496
{ XT_STAT_IND_BYTES_IN, "Index Bytes Read", "ind", "in", XT_STAT_ACCUMULATIVE | XT_STAT_BYTE_COUNT,
497
"Bytes read from the index files" },
498
{ XT_STAT_IND_BYTES_OUT, "Index Bytes Written", "ind", "out", XT_STAT_ACCUMULATIVE | XT_STAT_BYTE_COUNT,
499
"Bytes written from the index files" },
500
{ XT_STAT_IND_SYNC_COUNT, "Index File Flushes", "ind", "syncs", XT_STAT_ACCUMULATIVE | XT_STAT_COMBO_FIELD,
501
"Number of flushes to index files" },
502
{ XT_STAT_IND_SYNC_TIME, "Index Flush Time", "ind", su_t_unit, XT_STAT_ACCUMULATIVE | XT_STAT_TIME_VALUE | XT_STAT_COMBO_FIELD_2,
503
"The time in %sseconds to flush index files" },
504
{ XT_STAT_IND_CACHE_HIT, "Index Cache Hits", "ind", "hits", XT_STAT_ACCUMULATIVE,
505
"Hits when accessing the index cache" },
506
{ XT_STAT_IND_CACHE_MISS, "Index Cache Misses", "ind", "miss", XT_STAT_ACCUMULATIVE,
507
"Misses when accessing the index cache" },
508
{ XT_STAT_IND_CACHE_USAGE, "Index Cache Usage", "ind", "%use", XT_STAT_PERCENTAGE,
509
"Percentage of index cache used" },
510
{ XT_STAT_ILOG_BYTES_IN, "Index Log Bytes In", "ilog", "in", XT_STAT_ACCUMULATIVE | XT_STAT_BYTE_COUNT,
511
"Bytes read from the index log files" },
512
{ XT_STAT_ILOG_BYTES_OUT, "Index Log Bytes Out", "ilog", "out", XT_STAT_ACCUMULATIVE | XT_STAT_BYTE_COUNT,
513
"Bytes written from the index log files" },
514
{ XT_STAT_ILOG_SYNC_COUNT, "Index Log File Syncs", "ilog", "syncs", XT_STAT_ACCUMULATIVE | XT_STAT_COMBO_FIELD,
515
"Number of flushes to index log files" },
516
{ XT_STAT_ILOG_SYNC_TIME, "Index Log Sync Time", "ilog", su_t_unit, XT_STAT_ACCUMULATIVE | XT_STAT_TIME_VALUE | XT_STAT_COMBO_FIELD_2,
517
"The time in %sseconds to flush index log files" },
519
{ XT_STAT_XLOG_BYTES_IN, "Xact Log Bytes In", "xlog", "in", XT_STAT_ACCUMULATIVE | XT_STAT_BYTE_COUNT,
520
"Bytes read from the transaction log files" },
521
{ XT_STAT_XLOG_BYTES_OUT, "Xact Log Bytes Out", "xlog", "out", XT_STAT_ACCUMULATIVE | XT_STAT_BYTE_COUNT,
522
"Bytes written from the transaction log files" },
523
{ XT_STAT_XLOG_SYNC_COUNT, "Xact Log File Syncs", "xlog", "syncs", XT_STAT_ACCUMULATIVE,
524
"Number of flushes to transaction log files" },
525
{ XT_STAT_XLOG_SYNC_TIME, "Xact Log Sync Time", "xlog", su_t_unit, XT_STAT_ACCUMULATIVE | XT_STAT_TIME_VALUE,
526
"The time in %sseconds to flush transaction log files" },
527
{ XT_STAT_XLOG_CACHE_HIT, "Xact Log Cache Hits", "xlog", "hits", XT_STAT_ACCUMULATIVE,
528
"Hits when accessing the transaction log cache" },
529
{ XT_STAT_XLOG_CACHE_MISS, "Xact Log Cache Misses","xlog", "miss", XT_STAT_ACCUMULATIVE,
530
"Misses when accessing the transaction log cache" },
531
{ XT_STAT_XLOG_CACHE_USAGE, "Xact Log Cache Usage", "xlog", "%use", XT_STAT_PERCENTAGE,
532
"Percentage of transaction log cache used" },
534
{ XT_STAT_DATA_BYTES_IN, "Data Log Bytes In", "data", "in", XT_STAT_ACCUMULATIVE | XT_STAT_BYTE_COUNT,
535
"Bytes read from the data log files" },
536
{ XT_STAT_DATA_BYTES_OUT, "Data Log Bytes Out", "data", "out", XT_STAT_ACCUMULATIVE | XT_STAT_BYTE_COUNT,
537
"Bytes written from the data log files" },
538
{ XT_STAT_DATA_SYNC_COUNT, "Data Log File Syncs", "data", "syncs", XT_STAT_ACCUMULATIVE,
539
"Number of flushes to data log files" },
540
{ XT_STAT_DATA_SYNC_TIME, "Data Log Sync Time", "data", su_t_unit, XT_STAT_ACCUMULATIVE | XT_STAT_TIME_VALUE,
541
"The time in %sseconds to flush data log files" },
543
{ XT_STAT_BYTES_TO_CHKPNT, "Bytes to Checkpoint", "to", "chkpt", XT_STAT_BYTE_COUNT,
544
"Bytes written to the log since the last checkpoint" },
545
{ XT_STAT_LOG_BYTES_TO_WRITE, "Log Bytes to Write", "to", "write", XT_STAT_BYTE_COUNT,
546
"Bytes written to the log, still to be written to the database" },
547
{ XT_STAT_BYTES_TO_SWEEP, "Log Bytes to Sweep", "to", "sweep", XT_STAT_BYTE_COUNT,
548
"Bytes written to the log, still to be read by the sweeper" },
549
{ XT_STAT_SWEEPER_WAITS, "Sweeper Wait on Xact", "sweep", "waits", XT_STAT_ACCUMULATIVE,
550
"Attempts to cleanup a transaction" },
552
{ XT_STAT_SCAN_INDEX, "Index Scan Count", "scan", "index", XT_STAT_ACCUMULATIVE,
553
"Number of index scans" },
554
{ XT_STAT_SCAN_TABLE, "Table Scan Count", "scan", "table", XT_STAT_ACCUMULATIVE,
555
"Number of table scans" },
556
{ XT_STAT_ROW_SELECT, "Select Row Count", "row", "sel", XT_STAT_ACCUMULATIVE,
557
"Number of rows selected" },
558
{ XT_STAT_ROW_INSERT, "Insert Row Count", "row", "ins", XT_STAT_ACCUMULATIVE,
559
"Number of rows inserted" },
560
{ XT_STAT_ROW_UPDATE, "Update Row Count", "row", "upd", XT_STAT_ACCUMULATIVE,
561
"Number of rows updated" },
562
{ XT_STAT_ROW_DELETE, "Delete Row Count", "row", "del", XT_STAT_ACCUMULATIVE,
563
"Number of rows deleted" },
565
{ XT_STAT_RETRY_INDEX_SCAN, "Index Scan Retries", "retry", "iscan", XT_STAT_ACCUMULATIVE,
566
"Index scans restarted because of locked record" },
567
{ XT_STAT_REREAD_REC_LIST, "Record List Rereads", "retry", "rlist", XT_STAT_ACCUMULATIVE,
568
"Record list rescanned due to lock" },
570
{ XT_STAT_IND_CACHE_DIRTY, "Index Cache Dirty", "ind", "%dty", XT_STAT_PERCENTAGE,
571
"Percentage of index cache that is dirty" },
573
#ifdef XT_TIME_DISK_WRITES
574
{ XT_STAT_REC_WRITE_TIME, "Record Write Time", "rec", "w/ms", XT_STAT_ACCUMULATIVE | XT_STAT_TIME_VALUE,
575
"The time in %sseconds to write record/row files" },
576
{ XT_STAT_IND_WRITE_TIME, "Index Write Time", "ind", "w/ms", XT_STAT_ACCUMULATIVE | XT_STAT_TIME_VALUE,
577
"The time in %sseconds to write index files" },
578
{ XT_STAT_ILOG_WRITE_TIME, "Index Log Write Time", "ilog", "w/ms", XT_STAT_ACCUMULATIVE | XT_STAT_TIME_VALUE,
579
"The time in %sseconds to index log files" },
580
{ XT_STAT_XLOG_WRITE_TIME, "Xact Log Write Time", "*xlog", "w/ms", XT_STAT_ACCUMULATIVE | XT_STAT_TIME_VALUE,
581
"The time in %sseconds to transaction log files" },
582
{ XT_STAT_DATA_WRITE_TIME, "Data Log Write Time", "*data", "w/ms", XT_STAT_ACCUMULATIVE | XT_STAT_TIME_VALUE,
583
"The time in %sseconds to write data log files" }
586
#ifdef XT_TIME_DISK_READS
588
{ XT_STAT_REC_READ_TIME, "Record Read Time", "rec", "r/ms", XT_STAT_ACCUMULATIVE | XT_STAT_TIME_VALUE,
589
"The time in %sseconds to read record/row files" },
590
{ XT_STAT_IND_READ_TIME, "Index Read Time", "ind", "r/ms", XT_STAT_ACCUMULATIVE | XT_STAT_TIME_VALUE,
591
"The time in %sseconds to read index files" },
592
{ XT_STAT_LOG_READ_TIME, "Log Read Time", "log", "r/ms", XT_STAT_ACCUMULATIVE | XT_STAT_TIME_VALUE,
593
"The time in %sseconds to read index, transaction and data log files" },
597
static int pbxt_stat_meta_order[XT_STAT_MAXIMUM] = {
598
XT_STAT_TIME_CURRENT,
602
XT_STAT_WAIT_FOR_XACT,
603
XT_STAT_XACT_TO_CLEAN,
606
XT_STAT_REC_BYTES_IN,
607
XT_STAT_REC_BYTES_OUT,
608
#ifdef XT_TIME_DISK_READS
609
XT_STAT_REC_READ_TIME,
611
#ifdef XT_TIME_DISK_WRITES
612
XT_STAT_REC_WRITE_TIME,
614
XT_STAT_REC_SYNC_COUNT,
615
XT_STAT_REC_SYNC_TIME,
616
XT_STAT_REC_CACHE_HIT,
617
XT_STAT_REC_CACHE_MISS,
618
XT_STAT_REC_CACHE_FREES,
619
XT_STAT_REC_CACHE_USAGE,
620
XT_STAT_IND_BYTES_IN,
621
XT_STAT_IND_BYTES_OUT,
622
#ifdef XT_TIME_DISK_READS
623
XT_STAT_IND_READ_TIME,
625
#ifdef XT_TIME_DISK_WRITES
626
XT_STAT_IND_WRITE_TIME,
628
XT_STAT_IND_SYNC_COUNT,
629
XT_STAT_IND_SYNC_TIME,
630
XT_STAT_IND_CACHE_HIT,
631
XT_STAT_IND_CACHE_MISS,
632
XT_STAT_IND_CACHE_USAGE,
633
XT_STAT_IND_CACHE_DIRTY,
634
XT_STAT_ILOG_BYTES_IN,
635
XT_STAT_ILOG_BYTES_OUT,
636
#ifdef XT_TIME_DISK_WRITES
637
XT_STAT_ILOG_WRITE_TIME,
639
XT_STAT_ILOG_SYNC_COUNT,
640
XT_STAT_ILOG_SYNC_TIME,
641
XT_STAT_XLOG_BYTES_IN,
642
XT_STAT_XLOG_BYTES_OUT,
643
#ifdef XT_TIME_DISK_WRITES
644
XT_STAT_XLOG_WRITE_TIME,
646
XT_STAT_XLOG_SYNC_COUNT,
647
XT_STAT_XLOG_SYNC_TIME,
648
XT_STAT_XLOG_CACHE_HIT,
649
XT_STAT_XLOG_CACHE_MISS,
650
XT_STAT_XLOG_CACHE_USAGE,
651
XT_STAT_DATA_BYTES_IN,
652
XT_STAT_DATA_BYTES_OUT,
653
#ifdef XT_TIME_DISK_WRITES
654
XT_STAT_DATA_WRITE_TIME,
656
XT_STAT_DATA_SYNC_COUNT,
657
XT_STAT_DATA_SYNC_TIME,
658
XT_STAT_BYTES_TO_CHKPNT,
659
#ifdef XT_TIME_DISK_READS
660
XT_STAT_LOG_READ_TIME,
662
XT_STAT_LOG_BYTES_TO_WRITE,
663
XT_STAT_BYTES_TO_SWEEP,
664
XT_STAT_SWEEPER_WAITS,
671
XT_STAT_RETRY_INDEX_SCAN,
672
XT_STAT_REREAD_REC_LIST
675
xtPublic XTStatMetaDataPtr xt_get_stat_meta_data(int i)
677
return &pbxt_stat_meta_data[i];
680
/* This is the default order of statistics for display: */
681
xtPublic int xt_get_stat_meta_order(int i)
683
return pbxt_stat_meta_order[i];
686
xtPublic void xt_set_time_unit(const char *u)
688
xt_strcpy(10, su_t_unit, u);