~linuxjedi/drizzle/trunk-bug-667053

« back to all changes in this revision

Viewing changes to storage/innobase/include/ut0byte.ic

  • 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
Utilities for byte operations
 
3
 
 
4
(c) 1994, 1995 Innobase Oy
 
5
 
 
6
Created 5/30/1994 Heikki Tuuri
 
7
*******************************************************************/
 
8
 
 
9
/***********************************************************
 
10
Creates a 64-bit dulint out of two ulints. */
 
11
UNIV_INLINE
 
12
dulint
 
13
ut_dulint_create(
 
14
/*=============*/
 
15
                        /* out: created dulint */
 
16
        ulint   high,   /* in: high-order 32 bits */
 
17
        ulint   low)    /* in: low-order 32 bits */
 
18
{
 
19
        dulint  res;
 
20
 
 
21
        ut_ad(high <= 0xFFFFFFFF);
 
22
        ut_ad(low <= 0xFFFFFFFF);
 
23
 
 
24
        res.high = high;
 
25
        res.low  = low;
 
26
 
 
27
        return(res);
 
28
}
 
29
 
 
30
/***********************************************************
 
31
Gets the high-order 32 bits of a dulint. */
 
32
UNIV_INLINE
 
33
ulint
 
34
ut_dulint_get_high(
 
35
/*===============*/
 
36
                        /* out: 32 bits in ulint */
 
37
        dulint  d)      /* in: dulint */
 
38
{
 
39
        return(d.high);
 
40
}
 
41
 
 
42
/***********************************************************
 
43
Gets the low-order 32 bits of a dulint. */
 
44
UNIV_INLINE
 
45
ulint
 
46
ut_dulint_get_low(
 
47
/*==============*/
 
48
                        /* out: 32 bits in ulint */
 
49
        dulint  d)      /* in: dulint */
 
50
{
 
51
        return(d.low);
 
52
}
 
53
 
 
54
/***********************************************************
 
55
Converts a dulint (a struct of 2 ulints) to ib_longlong, which is a 64-bit
 
56
integer type. */
 
57
UNIV_INLINE
 
58
ib_longlong
 
59
ut_conv_dulint_to_longlong(
 
60
/*=======================*/
 
61
                        /* out: value in ib_longlong type */
 
62
        dulint  d)      /* in: dulint */
 
63
{
 
64
        return((ib_longlong)d.low
 
65
               + (((ib_longlong)d.high) << 32));
 
66
}
 
67
 
 
68
/***********************************************************
 
69
Tests if a dulint is zero. */
 
70
UNIV_INLINE
 
71
ibool
 
72
ut_dulint_is_zero(
 
73
/*==============*/
 
74
                        /* out: TRUE if zero */
 
75
        dulint  a)      /* in: dulint */
 
76
{
 
77
        if ((a.low == 0) && (a.high == 0)) {
 
78
 
 
79
                return(TRUE);
 
80
        }
 
81
 
 
82
        return(FALSE);
 
83
}
 
84
 
 
85
/***********************************************************
 
86
Compares two dulints. */
 
87
UNIV_INLINE
 
88
int
 
89
ut_dulint_cmp(
 
90
/*==========*/
 
91
                        /* out: -1 if a < b, 0 if a == b,
 
92
                        1 if a > b */
 
93
        dulint  a,      /* in: dulint */
 
94
        dulint  b)      /* in: dulint */
 
95
{
 
96
        if (a.high > b.high) {
 
97
                return(1);
 
98
        } else if (a.high < b.high) {
 
99
                return(-1);
 
100
        } else if (a.low > b.low) {
 
101
                return(1);
 
102
        } else if (a.low < b.low) {
 
103
                return(-1);
 
104
        } else {
 
105
                return(0);
 
106
        }
 
107
}
 
108
 
 
109
/***********************************************************
 
110
Calculates the max of two dulints. */
 
111
UNIV_INLINE
 
112
dulint
 
113
ut_dulint_get_max(
 
114
/*==============*/
 
115
                        /* out: max(a, b) */
 
116
        dulint  a,      /* in: dulint */
 
117
        dulint  b)      /* in: dulint */
 
118
{
 
119
        if (ut_dulint_cmp(a, b) > 0) {
 
120
 
 
121
                return(a);
 
122
        }
 
123
 
 
124
        return(b);
 
125
}
 
126
 
 
127
/***********************************************************
 
128
Calculates the min of two dulints. */
 
129
UNIV_INLINE
 
130
dulint
 
131
ut_dulint_get_min(
 
132
/*==============*/
 
133
                        /* out: min(a, b) */
 
134
        dulint  a,      /* in: dulint */
 
135
        dulint  b)      /* in: dulint */
 
136
{
 
137
        if (ut_dulint_cmp(a, b) > 0) {
 
138
 
 
139
                return(b);
 
140
        }
 
141
 
 
142
        return(a);
 
143
}
 
144
 
 
145
/***********************************************************
 
146
Adds a ulint to a dulint. */
 
147
UNIV_INLINE
 
148
dulint
 
149
ut_dulint_add(
 
150
/*==========*/
 
151
                        /* out: sum a + b */
 
152
        dulint  a,      /* in: dulint */
 
153
        ulint   b)      /* in: ulint */
 
154
{
 
155
        if (0xFFFFFFFFUL - b >= a.low) {
 
156
                a.low += b;
 
157
 
 
158
                return(a);
 
159
        }
 
160
 
 
161
        a.low = a.low - (0xFFFFFFFFUL - b) - 1;
 
162
 
 
163
        a.high++;
 
164
 
 
165
        return(a);
 
166
}
 
167
 
 
168
/***********************************************************
 
169
Subtracts a ulint from a dulint. */
 
170
UNIV_INLINE
 
171
dulint
 
172
ut_dulint_subtract(
 
173
/*===============*/
 
174
                        /* out: a - b */
 
175
        dulint  a,      /* in: dulint */
 
176
        ulint   b)      /* in: ulint, b <= a */
 
177
{
 
178
        if (a.low >= b) {
 
179
                a.low -= b;
 
180
 
 
181
                return(a);
 
182
        }
 
183
 
 
184
        b -= a.low + 1;
 
185
 
 
186
        a.low = 0xFFFFFFFFUL - b;
 
187
 
 
188
        ut_ad(a.high > 0);
 
189
 
 
190
        a.high--;
 
191
 
 
192
        return(a);
 
193
}
 
194
 
 
195
/***********************************************************
 
196
Subtracts a dulint from another. NOTE that the difference must be positive
 
197
and smaller that 4G. */
 
198
UNIV_INLINE
 
199
ulint
 
200
ut_dulint_minus(
 
201
/*============*/
 
202
                        /* out: a - b */
 
203
        dulint  a,      /* in: dulint; NOTE a must be >= b and at most
 
204
                        2 to power 32 - 1 greater */
 
205
        dulint  b)      /* in: dulint */
 
206
{
 
207
        ulint   diff;
 
208
 
 
209
        if (a.high == b.high) {
 
210
                ut_ad(a.low >= b.low);
 
211
 
 
212
                return(a.low - b.low);
 
213
        }
 
214
 
 
215
        ut_ad(a.high == b.high + 1);
 
216
 
 
217
        diff = (ulint)(0xFFFFFFFFUL - b.low);
 
218
        diff += 1 + a.low;
 
219
 
 
220
        ut_ad(diff > a.low);
 
221
 
 
222
        return(diff);
 
223
}
 
224
 
 
225
/************************************************************
 
226
Rounds a dulint downward to a multiple of a power of 2. */
 
227
UNIV_INLINE
 
228
dulint
 
229
ut_dulint_align_down(
 
230
/*=================*/
 
231
                                /* out: rounded value */
 
232
        dulint   n,             /* in: number to be rounded */
 
233
        ulint    align_no)      /* in: align by this number which must be a
 
234
                                power of 2 */
 
235
{
 
236
        ulint   low, high;
 
237
 
 
238
        ut_ad(align_no > 0);
 
239
        ut_ad(((align_no - 1) & align_no) == 0);
 
240
 
 
241
        low = ut_dulint_get_low(n);
 
242
        high = ut_dulint_get_high(n);
 
243
 
 
244
        low = low & ~(align_no - 1);
 
245
 
 
246
        return(ut_dulint_create(high, low));
 
247
}
 
248
 
 
249
/************************************************************
 
250
Rounds a dulint upward to a multiple of a power of 2. */
 
251
UNIV_INLINE
 
252
dulint
 
253
ut_dulint_align_up(
 
254
/*===============*/
 
255
                                /* out: rounded value */
 
256
        dulint   n,             /* in: number to be rounded */
 
257
        ulint    align_no)      /* in: align by this number which must be a
 
258
                                power of 2 */
 
259
{
 
260
        return(ut_dulint_align_down(ut_dulint_add(n, align_no - 1), align_no));
 
261
}
 
262
 
 
263
/************************************************************
 
264
The following function calculates the value of an integer n rounded
 
265
to the least product of align_no which is >= n. align_no
 
266
has to be a power of 2. */
 
267
UNIV_INLINE
 
268
ulint
 
269
ut_calc_align(
 
270
/*==========*/
 
271
                                /* out: rounded value */
 
272
        ulint    n,             /* in: number to be rounded */
 
273
        ulint    align_no)      /* in: align by this number */
 
274
{
 
275
        ut_ad(align_no > 0);
 
276
        ut_ad(((align_no - 1) & align_no) == 0);
 
277
 
 
278
        return((n + align_no - 1) & ~(align_no - 1));
 
279
}
 
280
 
 
281
/*************************************************************
 
282
The following function rounds up a pointer to the nearest aligned address. */
 
283
UNIV_INLINE
 
284
void*
 
285
ut_align(
 
286
/*=====*/
 
287
                                /* out: aligned pointer */
 
288
        void*   ptr,            /* in: pointer */
 
289
        ulint   align_no)       /* in: align by this number */
 
290
{
 
291
        ut_ad(align_no > 0);
 
292
        ut_ad(((align_no - 1) & align_no) == 0);
 
293
        ut_ad(ptr);
 
294
 
 
295
        ut_ad(sizeof(void*) == sizeof(ulint));
 
296
 
 
297
        return((void*)((((ulint)ptr) + align_no - 1) & ~(align_no - 1)));
 
298
}
 
299
 
 
300
/************************************************************
 
301
The following function calculates the value of an integer n rounded
 
302
to the biggest product of align_no which is <= n. align_no has to be a
 
303
power of 2. */
 
304
UNIV_INLINE
 
305
ulint
 
306
ut_calc_align_down(
 
307
/*===============*/
 
308
                                /* out: rounded value */
 
309
        ulint    n,              /* in: number to be rounded */
 
310
        ulint    align_no)       /* in: align by this number */
 
311
{
 
312
        ut_ad(align_no > 0);
 
313
        ut_ad(((align_no - 1) & align_no) == 0);
 
314
 
 
315
        return(n & ~(align_no - 1));
 
316
}
 
317
 
 
318
/*************************************************************
 
319
The following function rounds down a pointer to the nearest
 
320
aligned address. */
 
321
UNIV_INLINE
 
322
void*
 
323
ut_align_down(
 
324
/*==========*/
 
325
                                /* out: aligned pointer */
 
326
        void*   ptr,            /* in: pointer */
 
327
        ulint   align_no)       /* in: align by this number */
 
328
{
 
329
        ut_ad(align_no > 0);
 
330
        ut_ad(((align_no - 1) & align_no) == 0);
 
331
        ut_ad(ptr);
 
332
 
 
333
        ut_ad(sizeof(void*) == sizeof(ulint));
 
334
 
 
335
        return((void*)((((ulint)ptr)) & ~(align_no - 1)));
 
336
}
 
337
 
 
338
/*************************************************************
 
339
The following function computes the offset of a pointer from the nearest
 
340
aligned address. */
 
341
UNIV_INLINE
 
342
ulint
 
343
ut_align_offset(
 
344
/*============*/
 
345
                                        /* out: distance from
 
346
                                        aligned pointer */
 
347
        const void*     ptr,            /* in: pointer */
 
348
        ulint           align_no)       /* in: align by this number */
 
349
{
 
350
        ut_ad(align_no > 0);
 
351
        ut_ad(((align_no - 1) & align_no) == 0);
 
352
        ut_ad(ptr);
 
353
 
 
354
        ut_ad(sizeof(void*) == sizeof(ulint));
 
355
 
 
356
        return(((ulint)ptr) & (align_no - 1));
 
357
}
 
358
 
 
359
/*********************************************************************
 
360
Gets the nth bit of a ulint. */
 
361
UNIV_INLINE
 
362
ibool
 
363
ut_bit_get_nth(
 
364
/*===========*/
 
365
                        /* out: TRUE if nth bit is 1; 0th bit is defined to
 
366
                        be the least significant */
 
367
        ulint   a,      /* in: ulint */
 
368
        ulint   n)      /* in: nth bit requested */
 
369
{
 
370
        ut_ad(n < 8 * sizeof(ulint));
 
371
#if TRUE != 1
 
372
# error "TRUE != 1"
 
373
#endif
 
374
        return(1 & (a >> n));
 
375
}
 
376
 
 
377
/*********************************************************************
 
378
Sets the nth bit of a ulint. */
 
379
UNIV_INLINE
 
380
ulint
 
381
ut_bit_set_nth(
 
382
/*===========*/
 
383
                        /* out: the ulint with the bit set as requested */
 
384
        ulint   a,      /* in: ulint */
 
385
        ulint   n,      /* in: nth bit requested */
 
386
        ibool   val)    /* in: value for the bit to set */
 
387
{
 
388
        ut_ad(n < 8 * sizeof(ulint));
 
389
#if TRUE != 1
 
390
# error "TRUE != 1"
 
391
#endif
 
392
        if (val) {
 
393
                return(((ulint) 1 << n) | a);
 
394
        } else {
 
395
                return(~((ulint) 1 << n) & a);
 
396
        }
 
397
}