~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/innobase/ut/ut0ut.c

  • Committer: Monty Taylor
  • Date: 2008-10-16 06:32:59 UTC
  • mfrom: (518 drizzle)
  • mto: (511.1.5 codestyle)
  • mto: This revision was merged to the branch mainline in revision 521.
  • Revision ID: monty@inaugust.com-20081016063259-fwbqogq7lnezct0l
Merged with trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*******************************************************************
 
2
Various utilities for Innobase.
 
3
 
 
4
(c) 1994, 1995 Innobase Oy
 
5
 
 
6
Created 5/11/1994 Heikki Tuuri
 
7
********************************************************************/
 
8
 
 
9
#include "ut0ut.h"
 
10
 
 
11
#ifdef UNIV_NONINL
 
12
#include "ut0ut.ic"
 
13
#endif
 
14
 
 
15
#include <stdarg.h>
 
16
#include <string.h>
 
17
#include <ctype.h>
 
18
 
 
19
#include "ut0sort.h"
 
20
#include "trx0trx.h"
 
21
#include "ha_prototypes.h"
 
22
 
 
23
#if TIME_WITH_SYS_TIME
 
24
# include <sys/time.h>
 
25
# include <time.h>
 
26
#else
 
27
# if HAVE_SYS_TIME_H
 
28
#  include <sys/time.h>
 
29
# else
 
30
#  include <time.h>
 
31
# endif
 
32
#endif
 
33
 
 
34
ibool   ut_always_false = FALSE;
 
35
 
 
36
#ifdef __WIN__
 
37
/*********************************************************************
 
38
NOTE: The Windows epoch starts from 1601/01/01 whereas the Unix
 
39
epoch starts from 1970/1/1. For selection of constant see:
 
40
http://support.microsoft.com/kb/167296/ */
 
41
#define WIN_TO_UNIX_DELTA_USEC  ((ib_longlong) 11644473600000000ULL)
 
42
 
 
43
 
 
44
/*********************************************************************
 
45
This is the Windows version of gettimeofday(2).*/
 
46
static
 
47
int
 
48
ut_gettimeofday(
 
49
/*============*/
 
50
                        /* out: 0 if all OK else -1 */
 
51
        struct timeval* tv,     /* out: Values are relative to Unix epoch */
 
52
        void*           tz)     /* in: not used */
 
53
{
 
54
        FILETIME        ft;
 
55
        ib_longlong     tm;
 
56
 
 
57
        if (!tv) {
 
58
                errno = EINVAL;
 
59
                return(-1);
 
60
        }
 
61
 
 
62
        GetSystemTimeAsFileTime(&ft);
 
63
 
 
64
        tm = (ib_longlong) ft.dwHighDateTime << 32;
 
65
        tm |= ft.dwLowDateTime;
 
66
 
 
67
        ut_a(tm >= 0);  /* If tm wraps over to negative, the quotient / 10
 
68
                        does not work */
 
69
 
 
70
        tm /= 10;       /* Convert from 100 nsec periods to usec */
 
71
 
 
72
        /* If we don't convert to the Unix epoch the value for
 
73
        struct timeval::tv_sec will overflow.*/
 
74
        tm -= WIN_TO_UNIX_DELTA_USEC;
 
75
 
 
76
        tv->tv_sec  = (long) (tm / 1000000L);
 
77
        tv->tv_usec = (long) (tm % 1000000L);
 
78
 
 
79
        return(0);
 
80
}
 
81
#else
 
82
#define ut_gettimeofday         gettimeofday
 
83
#endif
 
84
 
 
85
/************************************************************
 
86
Gets the high 32 bits in a ulint. That is makes a shift >> 32,
 
87
but since there seem to be compiler bugs in both gcc and Visual C++,
 
88
we do this by a special conversion. */
 
89
 
 
90
ulint
 
91
ut_get_high32(
 
92
/*==========*/
 
93
                        /* out: a >> 32 */
 
94
        ulint   a)      /* in: ulint */
 
95
{
 
96
        ib_longlong     i;
 
97
 
 
98
        i = (ib_longlong)a;
 
99
 
 
100
        i = i >> 32;
 
101
 
 
102
        return((ulint)i);
 
103
}
 
104
 
 
105
/************************************************************
 
106
The following function returns elapsed CPU time in milliseconds. */
 
107
 
 
108
ulint
 
109
ut_clock(void)
 
110
{
 
111
        return((clock() * 1000) / CLOCKS_PER_SEC);
 
112
}
 
113
 
 
114
/**************************************************************
 
115
Returns system time. We do not specify the format of the time returned:
 
116
the only way to manipulate it is to use the function ut_difftime. */
 
117
 
 
118
ib_time_t
 
119
ut_time(void)
 
120
/*=========*/
 
121
{
 
122
        return(time(NULL));
 
123
}
 
124
 
 
125
/**************************************************************
 
126
Returns system time. */
 
127
 
 
128
void
 
129
ut_usectime(
 
130
/*========*/
 
131
        ulint*  sec,    /* out: seconds since the Epoch */
 
132
        ulint*  ms)     /* out: microseconds since the Epoch+*sec */
 
133
{
 
134
        struct timeval  tv;
 
135
 
 
136
        ut_gettimeofday(&tv, NULL);
 
137
        *sec = (ulint) tv.tv_sec;
 
138
        *ms  = (ulint) tv.tv_usec;
 
139
}
 
140
 
 
141
/**************************************************************
 
142
Returns the difference of two times in seconds. */
 
143
 
 
144
double
 
145
ut_difftime(
 
146
/*========*/
 
147
                                /* out: time2 - time1 expressed in seconds */
 
148
        ib_time_t       time2,  /* in: time */
 
149
        ib_time_t       time1)  /* in: time */
 
150
{
 
151
        return(difftime(time2, time1));
 
152
}
 
153
 
 
154
/**************************************************************
 
155
Prints a timestamp to a file. */
 
156
 
 
157
void
 
158
ut_print_timestamp(
 
159
/*===============*/
 
160
        FILE*  file) /* in: file where to print */
 
161
{
 
162
#ifdef __WIN__
 
163
        SYSTEMTIME cal_tm;
 
164
 
 
165
        GetLocalTime(&cal_tm);
 
166
 
 
167
        fprintf(file,"%02d%02d%02d %2d:%02d:%02d",
 
168
                (int)cal_tm.wYear % 100,
 
169
                (int)cal_tm.wMonth,
 
170
                (int)cal_tm.wDay,
 
171
                (int)cal_tm.wHour,
 
172
                (int)cal_tm.wMinute,
 
173
                (int)cal_tm.wSecond);
 
174
#else
 
175
        struct tm  cal_tm;
 
176
        struct tm* cal_tm_ptr;
 
177
        time_t     tm;
 
178
 
 
179
        time(&tm);
 
180
 
 
181
#ifdef HAVE_LOCALTIME_R
 
182
        localtime_r(&tm, &cal_tm);
 
183
        cal_tm_ptr = &cal_tm;
 
184
#else
 
185
        cal_tm_ptr = localtime(&tm);
 
186
#endif
 
187
        fprintf(file,"%02d%02d%02d %2d:%02d:%02d",
 
188
                cal_tm_ptr->tm_year % 100,
 
189
                cal_tm_ptr->tm_mon + 1,
 
190
                cal_tm_ptr->tm_mday,
 
191
                cal_tm_ptr->tm_hour,
 
192
                cal_tm_ptr->tm_min,
 
193
                cal_tm_ptr->tm_sec);
 
194
#endif
 
195
}
 
196
 
 
197
/**************************************************************
 
198
Sprintfs a timestamp to a buffer, 13..14 chars plus terminating NUL. */
 
199
 
 
200
void
 
201
ut_sprintf_timestamp(
 
202
/*=================*/
 
203
        char*   buf) /* in: buffer where to sprintf */
 
204
{
 
205
#ifdef __WIN__
 
206
        SYSTEMTIME cal_tm;
 
207
 
 
208
        GetLocalTime(&cal_tm);
 
209
 
 
210
        sprintf(buf, "%02d%02d%02d %2d:%02d:%02d",
 
211
                (int)cal_tm.wYear % 100,
 
212
                (int)cal_tm.wMonth,
 
213
                (int)cal_tm.wDay,
 
214
                (int)cal_tm.wHour,
 
215
                (int)cal_tm.wMinute,
 
216
                (int)cal_tm.wSecond);
 
217
#else
 
218
        struct tm  cal_tm;
 
219
        struct tm* cal_tm_ptr;
 
220
        time_t     tm;
 
221
 
 
222
        time(&tm);
 
223
 
 
224
#ifdef HAVE_LOCALTIME_R
 
225
        localtime_r(&tm, &cal_tm);
 
226
        cal_tm_ptr = &cal_tm;
 
227
#else
 
228
        cal_tm_ptr = localtime(&tm);
 
229
#endif
 
230
        sprintf(buf, "%02d%02d%02d %2d:%02d:%02d",
 
231
                cal_tm_ptr->tm_year % 100,
 
232
                cal_tm_ptr->tm_mon + 1,
 
233
                cal_tm_ptr->tm_mday,
 
234
                cal_tm_ptr->tm_hour,
 
235
                cal_tm_ptr->tm_min,
 
236
                cal_tm_ptr->tm_sec);
 
237
#endif
 
238
}
 
239
 
 
240
/**************************************************************
 
241
Sprintfs a timestamp to a buffer with no spaces and with ':' characters
 
242
replaced by '_'. */
 
243
 
 
244
void
 
245
ut_sprintf_timestamp_without_extra_chars(
 
246
/*=====================================*/
 
247
        char*   buf) /* in: buffer where to sprintf */
 
248
{
 
249
#ifdef __WIN__
 
250
        SYSTEMTIME cal_tm;
 
251
 
 
252
        GetLocalTime(&cal_tm);
 
253
 
 
254
        sprintf(buf, "%02d%02d%02d_%2d_%02d_%02d",
 
255
                (int)cal_tm.wYear % 100,
 
256
                (int)cal_tm.wMonth,
 
257
                (int)cal_tm.wDay,
 
258
                (int)cal_tm.wHour,
 
259
                (int)cal_tm.wMinute,
 
260
                (int)cal_tm.wSecond);
 
261
#else
 
262
        struct tm  cal_tm;
 
263
        struct tm* cal_tm_ptr;
 
264
        time_t     tm;
 
265
 
 
266
        time(&tm);
 
267
 
 
268
#ifdef HAVE_LOCALTIME_R
 
269
        localtime_r(&tm, &cal_tm);
 
270
        cal_tm_ptr = &cal_tm;
 
271
#else
 
272
        cal_tm_ptr = localtime(&tm);
 
273
#endif
 
274
        sprintf(buf, "%02d%02d%02d_%2d_%02d_%02d",
 
275
                cal_tm_ptr->tm_year % 100,
 
276
                cal_tm_ptr->tm_mon + 1,
 
277
                cal_tm_ptr->tm_mday,
 
278
                cal_tm_ptr->tm_hour,
 
279
                cal_tm_ptr->tm_min,
 
280
                cal_tm_ptr->tm_sec);
 
281
#endif
 
282
}
 
283
 
 
284
/**************************************************************
 
285
Returns current year, month, day. */
 
286
 
 
287
void
 
288
ut_get_year_month_day(
 
289
/*==================*/
 
290
        ulint*  year,   /* out: current year */
 
291
        ulint*  month,  /* out: month */
 
292
        ulint*  day)    /* out: day */
 
293
{
 
294
#ifdef __WIN__
 
295
        SYSTEMTIME cal_tm;
 
296
 
 
297
        GetLocalTime(&cal_tm);
 
298
 
 
299
        *year = (ulint)cal_tm.wYear;
 
300
        *month = (ulint)cal_tm.wMonth;
 
301
        *day = (ulint)cal_tm.wDay;
 
302
#else
 
303
        struct tm  cal_tm;
 
304
        struct tm* cal_tm_ptr;
 
305
        time_t     tm;
 
306
 
 
307
        time(&tm);
 
308
 
 
309
#ifdef HAVE_LOCALTIME_R
 
310
        localtime_r(&tm, &cal_tm);
 
311
        cal_tm_ptr = &cal_tm;
 
312
#else
 
313
        cal_tm_ptr = localtime(&tm);
 
314
#endif
 
315
        *year = (ulint)cal_tm_ptr->tm_year + 1900;
 
316
        *month = (ulint)cal_tm_ptr->tm_mon + 1;
 
317
        *day = (ulint)cal_tm_ptr->tm_mday;
 
318
#endif
 
319
}
 
320
 
 
321
/*****************************************************************
 
322
Runs an idle loop on CPU. The argument gives the desired delay
 
323
in microseconds on 100 MHz Pentium + Visual C++. */
 
324
 
 
325
ulint
 
326
ut_delay(
 
327
/*=====*/
 
328
                        /* out: dummy value */
 
329
        ulint   delay)  /* in: delay in microseconds on 100 MHz Pentium */
 
330
{
 
331
        ulint   i, j;
 
332
 
 
333
        j = 0;
 
334
 
 
335
        for (i = 0; i < delay * 50; i++) {
 
336
                j += i;
 
337
        }
 
338
 
 
339
        if (ut_always_false) {
 
340
                ut_always_false = (ibool) j;
 
341
        }
 
342
 
 
343
        return(j);
 
344
}
 
345
 
 
346
/*****************************************************************
 
347
Prints the contents of a memory buffer in hex and ascii. */
 
348
 
 
349
void
 
350
ut_print_buf(
 
351
/*=========*/
 
352
        FILE*           file,   /* in: file where to print */
 
353
        const void*     buf,    /* in: memory buffer */
 
354
        ulint           len)    /* in: length of the buffer */
 
355
{
 
356
        const byte*     data;
 
357
        ulint           i;
 
358
 
 
359
        UNIV_MEM_ASSERT_RW(buf, len);
 
360
 
 
361
        fprintf(file, " len %lu; hex ", len);
 
362
 
 
363
        for (data = (const byte*)buf, i = 0; i < len; i++) {
 
364
                fprintf(file, "%02lx", (ulong)*data++);
 
365
        }
 
366
 
 
367
        fputs("; asc ", file);
 
368
 
 
369
        data = (const byte*)buf;
 
370
 
 
371
        for (i = 0; i < len; i++) {
 
372
                int     c = (int) *data++;
 
373
                putc(isprint(c) ? c : ' ', file);
 
374
        }
 
375
 
 
376
        putc(';', file);
 
377
}
 
378
 
 
379
/****************************************************************
 
380
Sort function for ulint arrays. */
 
381
 
 
382
void
 
383
ut_ulint_sort(ulint* arr, ulint* aux_arr, ulint low, ulint high)
 
384
/*============================================================*/
 
385
{
 
386
        UT_SORT_FUNCTION_BODY(ut_ulint_sort, arr, aux_arr, low, high,
 
387
                              ut_ulint_cmp);
 
388
}
 
389
 
 
390
/*****************************************************************
 
391
Calculates fast the number rounded up to the nearest power of 2. */
 
392
 
 
393
ulint
 
394
ut_2_power_up(
 
395
/*==========*/
 
396
                        /* out: first power of 2 which is >= n */
 
397
        ulint   n)      /* in: number != 0 */
 
398
{
 
399
        ulint   res;
 
400
 
 
401
        res = 1;
 
402
 
 
403
        ut_ad(n > 0);
 
404
 
 
405
        while (res < n) {
 
406
                res = res * 2;
 
407
        }
 
408
 
 
409
        return(res);
 
410
}
 
411
 
 
412
/**************************************************************************
 
413
Outputs a NUL-terminated file name, quoted with apostrophes. */
 
414
 
 
415
void
 
416
ut_print_filename(
 
417
/*==============*/
 
418
        FILE*           f,      /* in: output stream */
 
419
        const char*     name)   /* in: name to print */
 
420
{
 
421
        putc('\'', f);
 
422
        for (;;) {
 
423
                int     c = *name++;
 
424
                switch (c) {
 
425
                case 0:
 
426
                        goto done;
 
427
                case '\'':
 
428
                        putc(c, f);
 
429
                        /* fall through */
 
430
                default:
 
431
                        putc(c, f);
 
432
                }
 
433
        }
 
434
done:
 
435
        putc('\'', f);
 
436
}
 
437
 
 
438
/**************************************************************************
 
439
Outputs a fixed-length string, quoted as an SQL identifier.
 
440
If the string contains a slash '/', the string will be
 
441
output as two identifiers separated by a period (.),
 
442
as in SQL database_name.identifier. */
 
443
 
 
444
void
 
445
ut_print_name(
 
446
/*==========*/
 
447
        FILE*           f,      /* in: output stream */
 
448
        trx_t*          trx,    /* in: transaction */
 
449
        ibool           table_id,/* in: TRUE=print a table name,
 
450
                                FALSE=print other identifier */
 
451
        const char*     name)   /* in: name to print */
 
452
{
 
453
        ut_print_namel(f, trx, table_id, name, strlen(name));
 
454
}
 
455
 
 
456
/**************************************************************************
 
457
Outputs a fixed-length string, quoted as an SQL identifier.
 
458
If the string contains a slash '/', the string will be
 
459
output as two identifiers separated by a period (.),
 
460
as in SQL database_name.identifier. */
 
461
 
 
462
void
 
463
ut_print_namel(
 
464
/*===========*/
 
465
        FILE*           f,      /* in: output stream */
 
466
        trx_t*          trx,    /* in: transaction (NULL=no quotes) */
 
467
        ibool           table_id,/* in: TRUE=print a table name,
 
468
                                FALSE=print other identifier */
 
469
        const char*     name,   /* in: name to print */
 
470
        ulint           namelen)/* in: length of name */
 
471
{
 
472
#ifdef UNIV_HOTBACKUP
 
473
        fwrite(name, 1, namelen, f);
 
474
#else
 
475
        if (table_id) {
 
476
                char*   slash = memchr(name, '/', namelen);
 
477
                if (!slash) {
 
478
 
 
479
                        goto no_db_name;
 
480
                }
 
481
 
 
482
                /* Print the database name and table name separately. */
 
483
                innobase_print_identifier(f, trx, TRUE, name, slash - name);
 
484
                putc('.', f);
 
485
                innobase_print_identifier(f, trx, TRUE, slash + 1,
 
486
                                          namelen - (slash - name) - 1);
 
487
        } else {
 
488
no_db_name:
 
489
                innobase_print_identifier(f, trx, table_id, name, namelen);
 
490
        }
 
491
#endif
 
492
}
 
493
 
 
494
/**************************************************************************
 
495
Catenate files. */
 
496
 
 
497
void
 
498
ut_copy_file(
 
499
/*=========*/
 
500
        FILE*   dest,   /* in: output file */
 
501
        FILE*   src)    /* in: input file to be appended to output */
 
502
{
 
503
        long    len = ftell(src);
 
504
        char    buf[4096];
 
505
 
 
506
        rewind(src);
 
507
        do {
 
508
                size_t  maxs = len < (long) sizeof buf
 
509
                        ? (size_t) len
 
510
                        : sizeof buf;
 
511
                size_t  size = fread(buf, 1, maxs, src);
 
512
                assert(fwrite(buf, 1, size, dest)==size);
 
513
                len -= (long) size;
 
514
                if (size < maxs) {
 
515
                        break;
 
516
                }
 
517
        } while (len > 0);
 
518
}
 
519
 
 
520
/**************************************************************************
 
521
snprintf(). */
 
522
 
 
523
#ifdef __WIN__
 
524
#include <stdarg.h>
 
525
int
 
526
ut_snprintf(
 
527
                                /* out: number of characters that would
 
528
                                have been printed if the size were
 
529
                                unlimited, not including the terminating
 
530
                                '\0'. */
 
531
        char*           str,    /* out: string */
 
532
        size_t          size,   /* in: str size */
 
533
        const char*     fmt,    /* in: format */
 
534
        ...)                    /* in: format values */
 
535
{
 
536
        int     res;
 
537
        va_list ap1;
 
538
        va_list ap2;
 
539
 
 
540
        va_start(ap1, fmt);
 
541
        va_start(ap2, fmt);
 
542
 
 
543
        res = _vscprintf(fmt, ap1);
 
544
        ut_a(res != -1);
 
545
 
 
546
        if (size > 0) {
 
547
                _vsnprintf(str, size, fmt, ap2);
 
548
 
 
549
                if ((size_t) res >= size) {
 
550
                        str[size - 1] = '\0';
 
551
                }
 
552
        }
 
553
 
 
554
        va_end(ap1);
 
555
        va_end(ap2);
 
556
 
 
557
        return(res);
 
558
}
 
559
#endif /* __WIN__ */