~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2009-05-11 17:50:22 UTC
  • Revision ID: brian@gaz-20090511175022-y35q9ky6uh9ldcjt
Replacing Sun employee copyright headers (aka... anything done by a Sun
employee is copyright by Sun).

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