~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Monty Taylor
  • Date: 2009-03-20 06:30:59 UTC
  • mfrom: (942.1.17 plugin-registration)
  • mto: This revision was merged to the branch mainline in revision 958.
  • Revision ID: mordred@inaugust.com-20090320063059-lr9hqvw15stxxgn3
Merged plugin registration branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved.
4
 
Copyright (c) 2009, Sun Microsystems, Inc.
5
 
 
6
 
Portions of this file contain modifications contributed and copyrighted by
7
 
Sun Microsystems, Inc. Those modifications are gratefully acknowledged and
8
 
are described briefly in the InnoDB documentation. The contributions by
9
 
Sun Microsystems are incorporated with their permission, and subject to the
10
 
conditions contained in the file COPYING.Sun_Microsystems.
 
3
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
11
4
 
12
5
This program is free software; you can redistribute it and/or modify it under
13
6
the terms of the GNU General Public License as published by the Free Software
18
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
19
12
 
20
13
You should have received a copy of the GNU General Public License along with
21
 
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
22
 
St, Fifth Floor, Boston, MA 02110-1301 USA
 
14
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 
15
Place, Suite 330, Boston, MA 02111-1307 USA
23
16
 
24
17
*****************************************************************************/
25
18
 
26
 
/***************************************************************//**
27
 
@file ut/ut0ut.c
 
19
/*******************************************************************
28
20
Various utilities for Innobase.
29
21
 
30
22
Created 5/11/1994 Heikki Tuuri
40
32
#include <string.h>
41
33
#include <ctype.h>
42
34
 
 
35
#include "trx0trx.h"
 
36
#include "ha_prototypes.h"
43
37
#ifndef UNIV_HOTBACKUP
44
 
# include "trx0trx.h"
45
38
# if defined(BUILD_DRIZZLE)
46
 
#  include "drizzled/common.h"
 
39
#  include <drizzled/common.h>
47
40
#  if TIME_WITH_SYS_TIME
48
41
#   include <sys/time.h>
49
42
#   include <time.h>
55
48
#   endif
56
49
#  endif
57
50
# else
58
 
#  include "ha_prototypes.h"
59
51
#  include "mysql_com.h" /* NAME_LEN */
60
52
# endif /* DRIZZLE */
61
53
#endif /* UNIV_HOTBACKUP */
62
 
#include <errno.h>
63
 
#include <assert.h>
64
54
 
65
 
/** A constant to prevent the compiler from optimizing ut_delay() away. */
66
55
UNIV_INTERN ibool       ut_always_false = FALSE;
67
56
 
68
57
#ifdef __WIN__
69
 
/*****************************************************************//**
 
58
/*********************************************************************
70
59
NOTE: The Windows epoch starts from 1601/01/01 whereas the Unix
71
60
epoch starts from 1970/1/1. For selection of constant see:
72
61
http://support.microsoft.com/kb/167296/ */
73
62
#define WIN_TO_UNIX_DELTA_USEC  ((ib_int64_t) 11644473600000000ULL)
74
63
 
75
64
 
76
 
/*****************************************************************//**
77
 
This is the Windows version of gettimeofday(2).
78
 
@return 0 if all OK else -1 */
 
65
/*********************************************************************
 
66
This is the Windows version of gettimeofday(2).*/
79
67
static
80
68
int
81
69
ut_gettimeofday(
82
70
/*============*/
83
 
        struct timeval* tv,     /*!< out: Values are relative to Unix epoch */
84
 
        void*           tz)     /*!< in: not used */
 
71
                        /* out: 0 if all OK else -1 */
 
72
        struct timeval* tv,     /* out: Values are relative to Unix epoch */
 
73
        void*           tz)     /* in: not used */
85
74
{
86
75
        FILETIME        ft;
87
76
        ib_int64_t      tm;
111
100
        return(0);
112
101
}
113
102
#else
114
 
/** An alias for gettimeofday(2).  On Microsoft Windows, we have to
115
 
reimplement this function. */
116
103
#define ut_gettimeofday         gettimeofday
117
104
#endif
118
105
 
119
 
/********************************************************//**
 
106
/************************************************************
120
107
Gets the high 32 bits in a ulint. That is makes a shift >> 32,
121
108
but since there seem to be compiler bugs in both gcc and Visual C++,
122
 
we do this by a special conversion.
123
 
@return a >> 32 */
 
109
we do this by a special conversion. */
124
110
UNIV_INTERN
125
111
ulint
126
112
ut_get_high32(
127
113
/*==========*/
128
 
        ulint   a)      /*!< in: ulint */
 
114
                        /* out: a >> 32 */
 
115
        ulint   a)      /* in: ulint */
129
116
{
130
117
        ib_int64_t      i;
131
118
 
136
123
        return((ulint)i);
137
124
}
138
125
 
139
 
/**********************************************************//**
 
126
/**************************************************************
140
127
Returns system time. We do not specify the format of the time returned:
141
 
the only way to manipulate it is to use the function ut_difftime.
142
 
@return system time */
 
128
the only way to manipulate it is to use the function ut_difftime. */
143
129
UNIV_INTERN
144
130
ib_time_t
145
131
ut_time(void)
148
134
        return(time(NULL));
149
135
}
150
136
 
151
 
#ifndef UNIV_HOTBACKUP
152
 
/**********************************************************//**
 
137
/**************************************************************
153
138
Returns system time.
154
139
Upon successful completion, the value 0 is returned; otherwise the
155
140
value -1 is returned and the global variable errno is set to indicate the
156
 
error.
157
 
@return 0 on success, -1 otherwise */
 
141
error. */
158
142
UNIV_INTERN
159
143
int
160
144
ut_usectime(
161
145
/*========*/
162
 
        ulint*  sec,    /*!< out: seconds since the Epoch */
163
 
        ulint*  ms)     /*!< out: microseconds since the Epoch+*sec */
 
146
                        /* out: 0 on success, -1 otherwise */
 
147
        ulint*  sec,    /* out: seconds since the Epoch */
 
148
        ulint*  ms)     /* out: microseconds since the Epoch+*sec */
164
149
{
165
150
        struct timeval  tv;
166
151
        int             ret;
191
176
        return(ret);
192
177
}
193
178
 
194
 
/**********************************************************//**
 
179
/**************************************************************
195
180
Returns the number of microseconds since epoch. Similar to
196
181
time(3), the return value is also stored in *tloc, provided
197
 
that tloc is non-NULL.
198
 
@return us since epoch */
 
182
that tloc is non-NULL. */
199
183
UNIV_INTERN
200
184
ullint
201
185
ut_time_us(
202
186
/*=======*/
203
 
        ullint* tloc)   /*!< out: us since epoch, if non-NULL */
 
187
                        /* out: us since epoch */
 
188
        ullint* tloc)   /* out: us since epoch, if non-NULL */
204
189
{
205
190
        struct timeval  tv;
206
191
        ullint          us;
216
201
        return(us);
217
202
}
218
203
 
219
 
/**********************************************************//**
220
 
Returns the number of milliseconds since some epoch.  The
221
 
value may wrap around.  It should only be used for heuristic
222
 
purposes.
223
 
@return ms since epoch */
224
 
UNIV_INTERN
225
 
ulint
226
 
ut_time_ms(void)
227
 
/*============*/
228
 
{
229
 
        struct timeval  tv;
230
 
 
231
 
        ut_gettimeofday(&tv, NULL);
232
 
 
233
 
        return((ulint) tv.tv_sec * 1000 + tv.tv_usec / 1000);
234
 
}
235
 
#endif /* !UNIV_HOTBACKUP */
236
 
 
237
 
/**********************************************************//**
238
 
Returns the difference of two times in seconds.
239
 
@return time2 - time1 expressed in seconds */
 
204
/**************************************************************
 
205
Returns the difference of two times in seconds. */
240
206
UNIV_INTERN
241
207
double
242
208
ut_difftime(
243
209
/*========*/
244
 
        ib_time_t       time2,  /*!< in: time */
245
 
        ib_time_t       time1)  /*!< in: time */
 
210
                                /* out: time2 - time1 expressed in seconds */
 
211
        ib_time_t       time2,  /* in: time */
 
212
        ib_time_t       time1)  /* in: time */
246
213
{
247
214
        return(difftime(time2, time1));
248
215
}
249
216
 
250
 
/**********************************************************//**
 
217
/**************************************************************
251
218
Prints a timestamp to a file. */
252
219
UNIV_INTERN
253
220
void
254
221
ut_print_timestamp(
255
222
/*===============*/
256
 
        FILE*  file) /*!< in: file where to print */
 
223
        FILE*  file) /* in: file where to print */
257
224
{
258
225
#ifdef __WIN__
259
226
        SYSTEMTIME cal_tm;
290
257
#endif
291
258
}
292
259
 
293
 
/**********************************************************//**
 
260
/**************************************************************
294
261
Sprintfs a timestamp to a buffer, 13..14 chars plus terminating NUL. */
295
262
UNIV_INTERN
296
263
void
297
264
ut_sprintf_timestamp(
298
265
/*=================*/
299
 
        char*   buf) /*!< in: buffer where to sprintf */
 
266
        char*   buf) /* in: buffer where to sprintf */
300
267
{
301
268
#ifdef __WIN__
302
269
        SYSTEMTIME cal_tm;
334
301
}
335
302
 
336
303
#ifdef UNIV_HOTBACKUP
337
 
/**********************************************************//**
 
304
/**************************************************************
338
305
Sprintfs a timestamp to a buffer with no spaces and with ':' characters
339
306
replaced by '_'. */
340
307
UNIV_INTERN
341
308
void
342
309
ut_sprintf_timestamp_without_extra_chars(
343
310
/*=====================================*/
344
 
        char*   buf) /*!< in: buffer where to sprintf */
 
311
        char*   buf) /* in: buffer where to sprintf */
345
312
{
346
313
#ifdef __WIN__
347
314
        SYSTEMTIME cal_tm;
378
345
#endif
379
346
}
380
347
 
381
 
/**********************************************************//**
 
348
/**************************************************************
382
349
Returns current year, month, day. */
383
350
UNIV_INTERN
384
351
void
385
352
ut_get_year_month_day(
386
353
/*==================*/
387
 
        ulint*  year,   /*!< out: current year */
388
 
        ulint*  month,  /*!< out: month */
389
 
        ulint*  day)    /*!< out: day */
 
354
        ulint*  year,   /* out: current year */
 
355
        ulint*  month,  /* out: month */
 
356
        ulint*  day)    /* out: day */
390
357
{
391
358
#ifdef __WIN__
392
359
        SYSTEMTIME cal_tm;
416
383
}
417
384
#endif /* UNIV_HOTBACKUP */
418
385
 
419
 
#ifndef UNIV_HOTBACKUP
420
 
/*************************************************************//**
 
386
/*****************************************************************
421
387
Runs an idle loop on CPU. The argument gives the desired delay
422
 
in microseconds on 100 MHz Pentium + Visual C++.
423
 
@return dummy value */
 
388
in microseconds on 100 MHz Pentium + Visual C++. */
424
389
UNIV_INTERN
425
390
ulint
426
391
ut_delay(
427
392
/*=====*/
428
 
        ulint   delay)  /*!< in: delay in microseconds on 100 MHz Pentium */
 
393
                        /* out: dummy value */
 
394
        ulint   delay)  /* in: delay in microseconds on 100 MHz Pentium */
429
395
{
430
396
        ulint   i, j;
431
397
 
433
399
 
434
400
        for (i = 0; i < delay * 50; i++) {
435
401
                j += i;
436
 
                UT_RELAX_CPU();
437
402
        }
438
403
 
439
404
        if (ut_always_false) {
442
407
 
443
408
        return(j);
444
409
}
445
 
#endif /* !UNIV_HOTBACKUP */
446
410
 
447
 
/*************************************************************//**
 
411
/*****************************************************************
448
412
Prints the contents of a memory buffer in hex and ascii. */
449
413
UNIV_INTERN
450
414
void
451
415
ut_print_buf(
452
416
/*=========*/
453
 
        FILE*           file,   /*!< in: file where to print */
454
 
        const void*     buf,    /*!< in: memory buffer */
455
 
        ulint           len)    /*!< in: length of the buffer */
 
417
        FILE*           file,   /* in: file where to print */
 
418
        const void*     buf,    /* in: memory buffer */
 
419
        ulint           len)    /* in: length of the buffer */
456
420
{
457
421
        const byte*     data;
458
422
        ulint           i;
477
441
        putc(';', file);
478
442
}
479
443
 
480
 
/*************************************************************//**
481
 
Calculates fast the number rounded up to the nearest power of 2.
482
 
@return first power of 2 which is >= n */
 
444
/*****************************************************************
 
445
Calculates fast the number rounded up to the nearest power of 2. */
483
446
UNIV_INTERN
484
447
ulint
485
448
ut_2_power_up(
486
449
/*==========*/
487
 
        ulint   n)      /*!< in: number != 0 */
 
450
                        /* out: first power of 2 which is >= n */
 
451
        ulint   n)      /* in: number != 0 */
488
452
{
489
453
        ulint   res;
490
454
 
499
463
        return(res);
500
464
}
501
465
 
502
 
/**********************************************************************//**
 
466
/**************************************************************************
503
467
Outputs a NUL-terminated file name, quoted with apostrophes. */
504
468
UNIV_INTERN
505
469
void
506
470
ut_print_filename(
507
471
/*==============*/
508
 
        FILE*           f,      /*!< in: output stream */
509
 
        const char*     name)   /*!< in: name to print */
 
472
        FILE*           f,      /* in: output stream */
 
473
        const char*     name)   /* in: name to print */
510
474
{
511
475
        putc('\'', f);
512
476
        for (;;) {
524
488
done:
525
489
        putc('\'', f);
526
490
}
527
 
#ifndef UNIV_HOTBACKUP
528
 
/**********************************************************************//**
 
491
 
 
492
/**************************************************************************
529
493
Outputs a fixed-length string, quoted as an SQL identifier.
530
494
If the string contains a slash '/', the string will be
531
495
output as two identifiers separated by a period (.),
534
498
void
535
499
ut_print_name(
536
500
/*==========*/
537
 
        FILE*           f,      /*!< in: output stream */
538
 
        trx_t*          trx,    /*!< in: transaction */
539
 
        ibool           table_id,/*!< in: TRUE=print a table name,
 
501
        FILE*           f,      /* in: output stream */
 
502
        trx_t*          trx,    /* in: transaction */
 
503
        ibool           table_id,/* in: TRUE=print a table name,
540
504
                                FALSE=print other identifier */
541
 
        const char*     name)   /*!< in: name to print */
 
505
        const char*     name)   /* in: name to print */
542
506
{
543
507
        ut_print_namel(f, trx, table_id, name, strlen(name));
544
508
}
545
509
 
546
 
/**********************************************************************//**
 
510
/**************************************************************************
547
511
Outputs a fixed-length string, quoted as an SQL identifier.
548
512
If the string contains a slash '/', the string will be
549
513
output as two identifiers separated by a period (.),
552
516
void
553
517
ut_print_namel(
554
518
/*===========*/
555
 
        FILE*           f,      /*!< in: output stream */
556
 
        trx_t*          trx,    /*!< in: transaction (NULL=no quotes) */
557
 
        ibool           table_id,/*!< in: TRUE=print a table name,
 
519
        FILE*           f,      /* in: output stream */
 
520
        trx_t*          trx,    /* in: transaction (NULL=no quotes) */
 
521
        ibool           table_id,/* in: TRUE=print a table name,
558
522
                                FALSE=print other identifier */
559
 
        const char*     name,   /*!< in: name to print */
560
 
        ulint           namelen)/*!< in: length of name */
 
523
        const char*     name,   /* in: name to print */
 
524
        ulint           namelen)/* in: length of name */
561
525
{
 
526
#ifdef UNIV_HOTBACKUP
 
527
        fwrite(name, 1, namelen, f);
 
528
#else
562
529
        /* 2 * NAME_LEN for database and table name,
563
530
        and some slack for the #mysql50# prefix and quotes */
564
531
        char            buf[3 * NAME_LEN];
571
538
 
572
539
        ssize_t ret= fwrite(buf, 1, bufend - buf, f);
573
540
        assert(ret==bufend-buf);  
 
541
#endif
574
542
}
575
543
 
576
 
/**********************************************************************//**
 
544
/**************************************************************************
577
545
Catenate files. */
578
546
UNIV_INTERN
579
547
void
580
548
ut_copy_file(
581
549
/*=========*/
582
 
        FILE*   dest,   /*!< in: output file */
583
 
        FILE*   src)    /*!< in: input file to be appended to output */
 
550
        FILE*   dest,   /* in: output file */
 
551
        FILE*   src)    /* in: input file to be appended to output */
584
552
{
585
553
        long    len = ftell(src);
586
554
        char    buf[4096];
599
567
                }
600
568
        } while (len > 0);
601
569
}
602
 
#endif /* !UNIV_HOTBACKUP */
 
570
 
 
571
/**************************************************************************
 
572
snprintf(). */
603
573
 
604
574
#ifdef __WIN__
605
 
# include <stdarg.h>
606
 
/**********************************************************************//**
607
 
A substitute for snprintf(3), formatted output conversion into
608
 
a limited buffer.
609
 
@return number of characters that would have been printed if the size
610
 
were unlimited, not including the terminating '\0'. */
611
 
UNIV_INTERN
 
575
#include <stdarg.h>
612
576
int
613
577
ut_snprintf(
614
 
/*========*/
615
 
        char*           str,    /*!< out: string */
616
 
        size_t          size,   /*!< in: str size */
617
 
        const char*     fmt,    /*!< in: format */
618
 
        ...)                    /*!< in: format values */
 
578
                                /* out: number of characters that would
 
579
                                have been printed if the size were
 
580
                                unlimited, not including the terminating
 
581
                                '\0'. */
 
582
        char*           str,    /* out: string */
 
583
        size_t          size,   /* in: str size */
 
584
        const char*     fmt,    /* in: format */
 
585
        ...)                    /* in: format values */
619
586
{
620
587
        int     res;
621
588
        va_list ap1;
641
608
        return(res);
642
609
}
643
610
#endif /* __WIN__ */
644
 
 
645
 
/*************************************************************//**
646
 
Convert an error number to a human readable text message. The
647
 
returned string is static and should not be freed or modified.
648
 
@return string, describing the error */
649
 
UNIV_INTERN
650
 
const char*
651
 
ut_strerr(
652
 
/*======*/
653
 
        enum db_err     num)    /*!< in: error number */
654
 
{
655
 
        switch (num) {
656
 
        case DB_SUCCESS:
657
 
                return("Success");
658
 
        case DB_SUCCESS_LOCKED_REC:
659
 
                return("Success, record lock created");
660
 
        case DB_ERROR:
661
 
                return("Generic error");
662
 
        case DB_INTERRUPTED:
663
 
                return("Operation interrupted");
664
 
        case DB_OUT_OF_MEMORY:
665
 
                return("Cannot allocate memory");
666
 
        case DB_OUT_OF_FILE_SPACE:
667
 
                return("Out of disk space");
668
 
        case DB_LOCK_WAIT:
669
 
                return("Lock wait");
670
 
        case DB_DEADLOCK:
671
 
                return("Deadlock");
672
 
        case DB_ROLLBACK:
673
 
                return("Rollback");
674
 
        case DB_DUPLICATE_KEY:
675
 
                return("Duplicate key");
676
 
        case DB_QUE_THR_SUSPENDED:
677
 
                return("The queue thread has been suspended");
678
 
        case DB_MISSING_HISTORY:
679
 
                return("Required history data has been deleted");
680
 
        case DB_CLUSTER_NOT_FOUND:
681
 
                return("Cluster not found");
682
 
        case DB_TABLE_NOT_FOUND:
683
 
                return("Table not found");
684
 
        case DB_MUST_GET_MORE_FILE_SPACE:
685
 
                return("More file space needed");
686
 
        case DB_TABLE_IS_BEING_USED:
687
 
                return("Table is being used");
688
 
        case DB_TOO_BIG_RECORD:
689
 
                return("Record too big");
690
 
        case DB_LOCK_WAIT_TIMEOUT:
691
 
                return("Lock wait timeout");
692
 
        case DB_NO_REFERENCED_ROW:
693
 
                return("Referenced key value not found");
694
 
        case DB_ROW_IS_REFERENCED:
695
 
                return("Row is referenced");
696
 
        case DB_CANNOT_ADD_CONSTRAINT:
697
 
                return("Cannot add constraint");
698
 
        case DB_CORRUPTION:
699
 
                return("Data structure corruption");
700
 
        case DB_COL_APPEARS_TWICE_IN_INDEX:
701
 
                return("Column appears twice in index");
702
 
        case DB_CANNOT_DROP_CONSTRAINT:
703
 
                return("Cannot drop constraint");
704
 
        case DB_NO_SAVEPOINT:
705
 
                return("No such savepoint");
706
 
        case DB_TABLESPACE_ALREADY_EXISTS:
707
 
                return("Tablespace already exists");
708
 
        case DB_TABLESPACE_DELETED:
709
 
                return("No such tablespace");
710
 
        case DB_LOCK_TABLE_FULL:
711
 
                return("Lock structs have exhausted the buffer pool");
712
 
        case DB_FOREIGN_DUPLICATE_KEY:
713
 
                return("Foreign key activated with duplicate keys");
714
 
        case DB_FOREIGN_EXCEED_MAX_CASCADE:
715
 
                return("Foreign key cascade delete/update exceeds max depth");
716
 
        case DB_TOO_MANY_CONCURRENT_TRXS:
717
 
                return("Too many concurrent transactions");
718
 
        case DB_UNSUPPORTED:
719
 
                return("Unsupported");
720
 
        case DB_PRIMARY_KEY_IS_NULL:
721
 
                return("Primary key is NULL");
722
 
        case DB_STATS_DO_NOT_EXIST:
723
 
                return("Persistent statistics do not exist");
724
 
        case DB_FAIL:
725
 
                return("Failed, retry may succeed");
726
 
        case DB_OVERFLOW:
727
 
                return("Overflow");
728
 
        case DB_UNDERFLOW:
729
 
                return("Underflow");
730
 
        case DB_STRONG_FAIL:
731
 
                return("Failed, retry will not succeed");
732
 
        case DB_ZIP_OVERFLOW:
733
 
                return("Zip overflow");
734
 
        case DB_RECORD_NOT_FOUND:
735
 
                return("Record not found");
736
 
        case DB_END_OF_INDEX:
737
 
                return("End of index");
738
 
        /* do not add default: in order to produce a warning if new code
739
 
        is added to the enum but not added here */
740
 
        }
741
 
 
742
 
        /* we abort here because if unknown error code is given, this could
743
 
        mean that memory corruption has happened and someone's error-code
744
 
        variable has been overwritten with bogus data */
745
 
        ut_error;
746
 
 
747
 
        /* NOT REACHED */
748
 
        return("Unknown error");
749
 
}