~drizzle-trunk/drizzle/development

1 by brian
clean slate
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
}