~drizzle-trunk/drizzle/development

641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
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
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
19
/******************************************************************
20
Utilities for byte operations
21
22
Created 5/30/1994 Heikki Tuuri
23
*******************************************************************/
24
25
/***********************************************************
26
Creates a 64-bit dulint out of two ulints. */
27
UNIV_INLINE
28
dulint
29
ut_dulint_create(
30
/*=============*/
31
			/* out: created dulint */
32
	ulint	high,	/* in: high-order 32 bits */
33
	ulint	low)	/* in: low-order 32 bits */
34
{
35
	dulint	res;
36
37
	ut_ad(high <= 0xFFFFFFFF);
38
	ut_ad(low <= 0xFFFFFFFF);
39
40
	res.high = high;
41
	res.low	 = low;
42
43
	return(res);
44
}
45
46
/***********************************************************
47
Gets the high-order 32 bits of a dulint. */
48
UNIV_INLINE
49
ulint
50
ut_dulint_get_high(
51
/*===============*/
52
			/* out: 32 bits in ulint */
53
	dulint	d)	/* in: dulint */
54
{
55
	return(d.high);
56
}
57
58
/***********************************************************
59
Gets the low-order 32 bits of a dulint. */
60
UNIV_INLINE
61
ulint
62
ut_dulint_get_low(
63
/*==============*/
64
			/* out: 32 bits in ulint */
65
	dulint	d)	/* in: dulint */
66
{
67
	return(d.low);
68
}
69
70
/***********************************************************
71
Converts a dulint (a struct of 2 ulints) to ib_int64_t, which is a 64-bit
72
integer type. */
73
UNIV_INLINE
74
ib_int64_t
75
ut_conv_dulint_to_longlong(
76
/*=======================*/
77
			/* out: value in ib_int64_t type */
78
	dulint	d)	/* in: dulint */
79
{
80
	return((ib_int64_t)d.low
81
	       + (((ib_int64_t)d.high) << 32));
82
}
83
84
/***********************************************************
85
Tests if a dulint is zero. */
86
UNIV_INLINE
87
ibool
88
ut_dulint_is_zero(
89
/*==============*/
90
			/* out: TRUE if zero */
91
	dulint	a)	/* in: dulint */
92
{
93
	if ((a.low == 0) && (a.high == 0)) {
94
95
		return(TRUE);
96
	}
97
98
	return(FALSE);
99
}
100
101
/***********************************************************
102
Compares two dulints. */
103
UNIV_INLINE
104
int
105
ut_dulint_cmp(
106
/*==========*/
107
			/* out: -1 if a < b, 0 if a == b,
108
			1 if a > b */
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
UNIV_INLINE
128
dulint
129
ut_dulint_get_max(
130
/*==============*/
131
			/* out: max(a, b) */
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
UNIV_INLINE
146
dulint
147
ut_dulint_get_min(
148
/*==============*/
149
			/* out: min(a, b) */
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
UNIV_INLINE
164
dulint
165
ut_dulint_add(
166
/*==========*/
167
			/* out: sum a + b */
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
UNIV_INLINE
187
dulint
188
ut_dulint_subtract(
189
/*===============*/
190
			/* out: a - b */
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
UNIV_INLINE
215
ulint
216
ut_dulint_minus(
217
/*============*/
218
			/* out: a - b */
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
UNIV_INLINE
244
dulint
245
ut_dulint_align_down(
246
/*=================*/
247
				/* out: rounded value */
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
UNIV_INLINE
268
dulint
269
ut_dulint_align_up(
270
/*===============*/
271
				/* out: rounded value */
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
UNIV_INLINE
282
ib_uint64_t
283
ut_uint64_align_down(
284
/*=================*/
285
					/* out: rounded value */
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
UNIV_INLINE
299
ib_uint64_t
300
ut_uint64_align_up(
301
/*===============*/
302
					/* out: rounded value */
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
UNIV_INLINE
318
void*
319
ut_align(
320
/*=====*/
321
				/* out: aligned pointer */
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
UNIV_INLINE
338
void*
339
ut_align_down(
340
/*==========*/
341
					/* out: aligned pointer */
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
UNIV_INLINE
358
ulint
359
ut_align_offset(
360
/*============*/
361
					/* out: distance from
362
					aligned pointer */
363
	const void*	ptr,		/* in: pointer */
364
	ulint		align_no)	/* in: align by this number */
365
{
366
	ut_ad(align_no > 0);
367
	ut_ad(((align_no - 1) & align_no) == 0);
368
	ut_ad(ptr);
369
370
	ut_ad(sizeof(void*) == sizeof(ulint));
371
372
	return(((ulint)ptr) & (align_no - 1));
373
}
374
375
/*********************************************************************
376
Gets the nth bit of a ulint. */
377
UNIV_INLINE
378
ibool
379
ut_bit_get_nth(
380
/*===========*/
381
			/* out: TRUE if nth bit is 1; 0th bit is defined to
382
			be the least significant */
383
	ulint	a,	/* in: ulint */
384
	ulint	n)	/* in: nth bit requested */
385
{
386
	ut_ad(n < 8 * sizeof(ulint));
387
#if TRUE != 1
388
# error "TRUE != 1"
389
#endif
390
	return(1 & (a >> n));
391
}
392
393
/*********************************************************************
394
Sets the nth bit of a ulint. */
395
UNIV_INLINE
396
ulint
397
ut_bit_set_nth(
398
/*===========*/
399
			/* out: the ulint with the bit set as requested */
400
	ulint	a,	/* in: ulint */
401
	ulint	n,	/* in: nth bit requested */
402
	ibool	val)	/* in: value for the bit to set */
403
{
404
	ut_ad(n < 8 * sizeof(ulint));
405
#if TRUE != 1
406
# error "TRUE != 1"
407
#endif
408
	if (val) {
409
		return(((ulint) 1 << n) | a);
410
	} else {
411
		return(~((ulint) 1 << n) & a);
412
	}
413
}