~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

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__ */