~ubuntu-branches/ubuntu/maverick/drizzle/maverick

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Monty Taylor
  • Date: 2010-03-18 12:12:31 UTC
  • Revision ID: james.westby@ubuntu.com-20100318121231-k6g1xe6cshbwa0f8
Tags: upstream-2010.03.1347
ImportĀ upstreamĀ versionĀ 2010.03.1347

Show diffs side-by-side

added added

removed removed

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