~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2009-02-21 00:18:15 UTC
  • Revision ID: brian@tangent.org-20090221001815-x20e8h71e984lvs1
Completion (?) of uint conversion.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*****************************************************************************
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.
11
 
 
12
 
This program is free software; you can redistribute it and/or modify it under
13
 
the terms of the GNU General Public License as published by the Free Software
14
 
Foundation; version 2 of the License.
15
 
 
16
 
This program is distributed in the hope that it will be useful, but WITHOUT
17
 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18
 
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
19
 
 
20
 
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
23
 
 
24
 
*****************************************************************************/
25
 
 
26
 
/***************************************************************//**
27
 
@file ut/ut0ut.c
 
1
/*******************************************************************
28
2
Various utilities for Innobase.
29
3
 
 
4
(c) 1994, 1995 Innobase Oy
 
5
 
30
6
Created 5/11/1994 Heikki Tuuri
31
7
********************************************************************/
32
8
 
40
16
#include <string.h>
41
17
#include <ctype.h>
42
18
 
 
19
#include "trx0trx.h"
 
20
#include "ha_prototypes.h"
43
21
#ifndef UNIV_HOTBACKUP
44
 
# include "trx0trx.h"
45
22
# if defined(BUILD_DRIZZLE)
46
 
#  include "drizzled/common.h"
 
23
#  include <drizzled/common.h>
47
24
#  if TIME_WITH_SYS_TIME
48
25
#   include <sys/time.h>
49
26
#   include <time.h>
55
32
#   endif
56
33
#  endif
57
34
# else
58
 
#  include "ha_prototypes.h"
59
35
#  include "mysql_com.h" /* NAME_LEN */
60
36
# endif /* DRIZZLE */
61
37
#endif /* UNIV_HOTBACKUP */
62
 
#include <errno.h>
63
 
#include <assert.h>
64
38
 
65
 
/** A constant to prevent the compiler from optimizing ut_delay() away. */
66
39
UNIV_INTERN ibool       ut_always_false = FALSE;
67
40
 
68
41
#ifdef __WIN__
69
 
/*****************************************************************//**
 
42
/*********************************************************************
70
43
NOTE: The Windows epoch starts from 1601/01/01 whereas the Unix
71
44
epoch starts from 1970/1/1. For selection of constant see:
72
45
http://support.microsoft.com/kb/167296/ */
73
46
#define WIN_TO_UNIX_DELTA_USEC  ((ib_int64_t) 11644473600000000ULL)
74
47
 
75
48
 
76
 
/*****************************************************************//**
77
 
This is the Windows version of gettimeofday(2).
78
 
@return 0 if all OK else -1 */
 
49
/*********************************************************************
 
50
This is the Windows version of gettimeofday(2).*/
79
51
static
80
52
int
81
53
ut_gettimeofday(
82
54
/*============*/
83
 
        struct timeval* tv,     /*!< out: Values are relative to Unix epoch */
84
 
        void*           tz)     /*!< in: not used */
 
55
                        /* out: 0 if all OK else -1 */
 
56
        struct timeval* tv,     /* out: Values are relative to Unix epoch */
 
57
        void*           tz)     /* in: not used */
85
58
{
86
59
        FILETIME        ft;
87
60
        ib_int64_t      tm;
111
84
        return(0);
112
85
}
113
86
#else
114
 
/** An alias for gettimeofday(2).  On Microsoft Windows, we have to
115
 
reimplement this function. */
116
87
#define ut_gettimeofday         gettimeofday
117
88
#endif
118
89
 
119
 
/********************************************************//**
 
90
/************************************************************
120
91
Gets the high 32 bits in a ulint. That is makes a shift >> 32,
121
92
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 */
 
93
we do this by a special conversion. */
124
94
UNIV_INTERN
125
95
ulint
126
96
ut_get_high32(
127
97
/*==========*/
128
 
        ulint   a)      /*!< in: ulint */
 
98
                        /* out: a >> 32 */
 
99
        ulint   a)      /* in: ulint */
129
100
{
130
101
        ib_int64_t      i;
131
102
 
136
107
        return((ulint)i);
137
108
}
138
109
 
139
 
/**********************************************************//**
 
110
/**************************************************************
140
111
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 */
 
112
the only way to manipulate it is to use the function ut_difftime. */
143
113
UNIV_INTERN
144
114
ib_time_t
145
115
ut_time(void)
148
118
        return(time(NULL));
149
119
}
150
120
 
151
 
#ifndef UNIV_HOTBACKUP
152
 
/**********************************************************//**
 
121
/**************************************************************
153
122
Returns system time.
154
123
Upon successful completion, the value 0 is returned; otherwise the
155
124
value -1 is returned and the global variable errno is set to indicate the
156
 
error.
157
 
@return 0 on success, -1 otherwise */
 
125
error. */
158
126
UNIV_INTERN
159
127
int
160
128
ut_usectime(
161
129
/*========*/
162
 
        ulint*  sec,    /*!< out: seconds since the Epoch */
163
 
        ulint*  ms)     /*!< out: microseconds since the Epoch+*sec */
 
130
                        /* out: 0 on success, -1 otherwise */
 
131
        ulint*  sec,    /* out: seconds since the Epoch */
 
132
        ulint*  ms)     /* out: microseconds since the Epoch+*sec */
164
133
{
165
134
        struct timeval  tv;
166
135
        int             ret;
191
160
        return(ret);
192
161
}
193
162
 
194
 
/**********************************************************//**
 
163
/**************************************************************
195
164
Returns the number of microseconds since epoch. Similar to
196
165
time(3), the return value is also stored in *tloc, provided
197
 
that tloc is non-NULL.
198
 
@return us since epoch */
 
166
that tloc is non-NULL. */
199
167
UNIV_INTERN
200
168
ullint
201
169
ut_time_us(
202
170
/*=======*/
203
 
        ullint* tloc)   /*!< out: us since epoch, if non-NULL */
 
171
                        /* out: us since epoch */
 
172
        ullint* tloc)   /* out: us since epoch, if non-NULL */
204
173
{
205
174
        struct timeval  tv;
206
175
        ullint          us;
216
185
        return(us);
217
186
}
218
187
 
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 */
 
188
/**************************************************************
 
189
Returns the difference of two times in seconds. */
240
190
UNIV_INTERN
241
191
double
242
192
ut_difftime(
243
193
/*========*/
244
 
        ib_time_t       time2,  /*!< in: time */
245
 
        ib_time_t       time1)  /*!< in: time */
 
194
                                /* out: time2 - time1 expressed in seconds */
 
195
        ib_time_t       time2,  /* in: time */
 
196
        ib_time_t       time1)  /* in: time */
246
197
{
247
198
        return(difftime(time2, time1));
248
199
}
249
200
 
250
 
/**********************************************************//**
 
201
/**************************************************************
251
202
Prints a timestamp to a file. */
252
203
UNIV_INTERN
253
204
void
254
205
ut_print_timestamp(
255
206
/*===============*/
256
 
        FILE*  file) /*!< in: file where to print */
 
207
        FILE*  file) /* in: file where to print */
257
208
{
258
209
#ifdef __WIN__
259
210
        SYSTEMTIME cal_tm;
290
241
#endif
291
242
}
292
243
 
293
 
/**********************************************************//**
 
244
/**************************************************************
294
245
Sprintfs a timestamp to a buffer, 13..14 chars plus terminating NUL. */
295
246
UNIV_INTERN
296
247
void
297
248
ut_sprintf_timestamp(
298
249
/*=================*/
299
 
        char*   buf) /*!< in: buffer where to sprintf */
 
250
        char*   buf) /* in: buffer where to sprintf */
300
251
{
301
252
#ifdef __WIN__
302
253
        SYSTEMTIME cal_tm;
333
284
#endif
334
285
}
335
286
 
336
 
#ifdef UNIV_HOTBACKUP
337
 
/**********************************************************//**
 
287
/**************************************************************
338
288
Sprintfs a timestamp to a buffer with no spaces and with ':' characters
339
289
replaced by '_'. */
340
290
UNIV_INTERN
341
291
void
342
292
ut_sprintf_timestamp_without_extra_chars(
343
293
/*=====================================*/
344
 
        char*   buf) /*!< in: buffer where to sprintf */
 
294
        char*   buf) /* in: buffer where to sprintf */
345
295
{
346
296
#ifdef __WIN__
347
297
        SYSTEMTIME cal_tm;
378
328
#endif
379
329
}
380
330
 
381
 
/**********************************************************//**
 
331
/**************************************************************
382
332
Returns current year, month, day. */
383
333
UNIV_INTERN
384
334
void
385
335
ut_get_year_month_day(
386
336
/*==================*/
387
 
        ulint*  year,   /*!< out: current year */
388
 
        ulint*  month,  /*!< out: month */
389
 
        ulint*  day)    /*!< out: day */
 
337
        ulint*  year,   /* out: current year */
 
338
        ulint*  month,  /* out: month */
 
339
        ulint*  day)    /* out: day */
390
340
{
391
341
#ifdef __WIN__
392
342
        SYSTEMTIME cal_tm;
414
364
        *day = (ulint)cal_tm_ptr->tm_mday;
415
365
#endif
416
366
}
417
 
#endif /* UNIV_HOTBACKUP */
418
367
 
419
 
#ifndef UNIV_HOTBACKUP
420
 
/*************************************************************//**
 
368
/*****************************************************************
421
369
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 */
 
370
in microseconds on 100 MHz Pentium + Visual C++. */
424
371
UNIV_INTERN
425
372
ulint
426
373
ut_delay(
427
374
/*=====*/
428
 
        ulint   delay)  /*!< in: delay in microseconds on 100 MHz Pentium */
 
375
                        /* out: dummy value */
 
376
        ulint   delay)  /* in: delay in microseconds on 100 MHz Pentium */
429
377
{
430
378
        ulint   i, j;
431
379
 
433
381
 
434
382
        for (i = 0; i < delay * 50; i++) {
435
383
                j += i;
436
 
                UT_RELAX_CPU();
437
384
        }
438
385
 
439
386
        if (ut_always_false) {
442
389
 
443
390
        return(j);
444
391
}
445
 
#endif /* !UNIV_HOTBACKUP */
446
392
 
447
 
/*************************************************************//**
 
393
/*****************************************************************
448
394
Prints the contents of a memory buffer in hex and ascii. */
449
395
UNIV_INTERN
450
396
void
451
397
ut_print_buf(
452
398
/*=========*/
453
 
        FILE*           file,   /*!< in: file where to print */
454
 
        const void*     buf,    /*!< in: memory buffer */
455
 
        ulint           len)    /*!< in: length of the buffer */
 
399
        FILE*           file,   /* in: file where to print */
 
400
        const void*     buf,    /* in: memory buffer */
 
401
        ulint           len)    /* in: length of the buffer */
456
402
{
457
403
        const byte*     data;
458
404
        ulint           i;
477
423
        putc(';', file);
478
424
}
479
425
 
480
 
/*************************************************************//**
481
 
Calculates fast the number rounded up to the nearest power of 2.
482
 
@return first power of 2 which is >= n */
 
426
/*****************************************************************
 
427
Calculates fast the number rounded up to the nearest power of 2. */
483
428
UNIV_INTERN
484
429
ulint
485
430
ut_2_power_up(
486
431
/*==========*/
487
 
        ulint   n)      /*!< in: number != 0 */
 
432
                        /* out: first power of 2 which is >= n */
 
433
        ulint   n)      /* in: number != 0 */
488
434
{
489
435
        ulint   res;
490
436
 
499
445
        return(res);
500
446
}
501
447
 
502
 
/**********************************************************************//**
 
448
/**************************************************************************
503
449
Outputs a NUL-terminated file name, quoted with apostrophes. */
504
450
UNIV_INTERN
505
451
void
506
452
ut_print_filename(
507
453
/*==============*/
508
 
        FILE*           f,      /*!< in: output stream */
509
 
        const char*     name)   /*!< in: name to print */
 
454
        FILE*           f,      /* in: output stream */
 
455
        const char*     name)   /* in: name to print */
510
456
{
511
457
        putc('\'', f);
512
458
        for (;;) {
524
470
done:
525
471
        putc('\'', f);
526
472
}
527
 
#ifndef UNIV_HOTBACKUP
528
 
/**********************************************************************//**
 
473
 
 
474
/**************************************************************************
529
475
Outputs a fixed-length string, quoted as an SQL identifier.
530
476
If the string contains a slash '/', the string will be
531
477
output as two identifiers separated by a period (.),
534
480
void
535
481
ut_print_name(
536
482
/*==========*/
537
 
        FILE*           f,      /*!< in: output stream */
538
 
        trx_t*          trx,    /*!< in: transaction */
539
 
        ibool           table_id,/*!< in: TRUE=print a table name,
 
483
        FILE*           f,      /* in: output stream */
 
484
        trx_t*          trx,    /* in: transaction */
 
485
        ibool           table_id,/* in: TRUE=print a table name,
540
486
                                FALSE=print other identifier */
541
 
        const char*     name)   /*!< in: name to print */
 
487
        const char*     name)   /* in: name to print */
542
488
{
543
489
        ut_print_namel(f, trx, table_id, name, strlen(name));
544
490
}
545
491
 
546
 
/**********************************************************************//**
 
492
/**************************************************************************
547
493
Outputs a fixed-length string, quoted as an SQL identifier.
548
494
If the string contains a slash '/', the string will be
549
495
output as two identifiers separated by a period (.),
552
498
void
553
499
ut_print_namel(
554
500
/*===========*/
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,
 
501
        FILE*           f,      /* in: output stream */
 
502
        trx_t*          trx,    /* in: transaction (NULL=no quotes) */
 
503
        ibool           table_id,/* in: TRUE=print a table name,
558
504
                                FALSE=print other identifier */
559
 
        const char*     name,   /*!< in: name to print */
560
 
        ulint           namelen)/*!< in: length of name */
 
505
        const char*     name,   /* in: name to print */
 
506
        ulint           namelen)/* in: length of name */
561
507
{
 
508
#ifdef UNIV_HOTBACKUP
 
509
        fwrite(name, 1, namelen, f);
 
510
#else
562
511
        /* 2 * NAME_LEN for database and table name,
563
512
        and some slack for the #mysql50# prefix and quotes */
564
513
        char            buf[3 * NAME_LEN];
571
520
 
572
521
        ssize_t ret= fwrite(buf, 1, bufend - buf, f);
573
522
        assert(ret==bufend-buf);  
 
523
#endif
574
524
}
575
525
 
576
 
/**********************************************************************//**
 
526
/**************************************************************************
577
527
Catenate files. */
578
528
UNIV_INTERN
579
529
void
580
530
ut_copy_file(
581
531
/*=========*/
582
 
        FILE*   dest,   /*!< in: output file */
583
 
        FILE*   src)    /*!< in: input file to be appended to output */
 
532
        FILE*   dest,   /* in: output file */
 
533
        FILE*   src)    /* in: input file to be appended to output */
584
534
{
585
535
        long    len = ftell(src);
586
536
        char    buf[4096];
599
549
                }
600
550
        } while (len > 0);
601
551
}
602
 
#endif /* !UNIV_HOTBACKUP */
 
552
 
 
553
/**************************************************************************
 
554
snprintf(). */
603
555
 
604
556
#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
 
557
#include <stdarg.h>
612
558
int
613
559
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 */
 
560
                                /* out: number of characters that would
 
561
                                have been printed if the size were
 
562
                                unlimited, not including the terminating
 
563
                                '\0'. */
 
564
        char*           str,    /* out: string */
 
565
        size_t          size,   /* in: str size */
 
566
        const char*     fmt,    /* in: format */
 
567
        ...)                    /* in: format values */
619
568
{
620
569
        int     res;
621
570
        va_list ap1;
641
590
        return(res);
642
591
}
643
592
#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_CHILD_NO_INDEX:
737
 
                return("No index on referencing keys in referencing table");
738
 
        case DB_PARENT_NO_INDEX:
739
 
                return("No index on referenced keys in referenced table");
740
 
        case DB_END_OF_INDEX:
741
 
                return("End of index");
742
 
        /* do not add default: in order to produce a warning if new code
743
 
        is added to the enum but not added here */
744
 
        }
745
 
 
746
 
        /* we abort here because if unknown error code is given, this could
747
 
        mean that memory corruption has happened and someone's error-code
748
 
        variable has been overwritten with bogus data */
749
 
        ut_error;
750
 
 
751
 
        /* NOT REACHED */
752
 
        return("Unknown error");
753
 
}