1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
/* Copyright (C) 2004-2005 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include <Bitmask.hpp>
#include <NdbOut.hpp>
void
BitmaskImpl::getFieldImpl(const Uint32 src[],
unsigned shiftL, unsigned len, Uint32 dst[])
{
/* Copy whole words of src to dst, shifting src left
* by shiftL. Undefined bits of the last written dst word
* should be zeroed.
*/
assert(shiftL < 32);
unsigned shiftR = 32 - shiftL;
unsigned undefined = shiftL ? ~0 : 0;
/* Merge first word with previously set bits if there's a shift */
* dst = shiftL ? * dst : 0;
/* Treat the zero-shift case separately to avoid
* trampling or reading past the end of src
*/
if (shiftL == 0)
{
while(len >= 32)
{
* dst++ = * src++;
len -=32;
}
if (len != 0)
{
/* Last word has some bits set */
Uint32 mask= ((1 << len) -1); // 0000111
* dst = (* src) & mask;
}
}
else // shiftL !=0, need to build each word from two words shifted
{
while(len >= 32)
{
* dst++ |= (* src) << shiftL;
* dst = ((* src++) >> shiftR) & undefined;
len -= 32;
}
/* Have space for shiftR more bits in the current dst word
* is that enough?
*/
if(len <= shiftR)
{
/* Fit the remaining bits in the current dst word */
* dst |= ((* src) & ((1 << len) - 1)) << shiftL;
}
else
{
/* Need to write to two dst words */
* dst++ |= ((* src) << shiftL);
* dst = ((* src) >> shiftR) & ((1 << (len - shiftR)) - 1) & undefined;
}
}
}
void
BitmaskImpl::setFieldImpl(Uint32 dst[],
unsigned shiftL, unsigned len, const Uint32 src[])
{
/**
*
* abcd ef00
* 00ab cdef
*/
assert(shiftL < 32);
unsigned shiftR = 32 - shiftL;
unsigned undefined = shiftL ? ~0 : 0;
while(len >= 32)
{
* dst = (* src++) >> shiftL;
* dst++ |= ((* src) << shiftR) & undefined;
len -= 32;
}
/* Copy last bits */
Uint32 mask = ((1 << len) -1);
* dst = (* dst & ~mask);
if(len <= shiftR)
{
/* Remaining bits fit in current word */
* dst |= ((* src++) >> shiftL) & mask;
}
else
{
/* Remaining bits update 2 words */
* dst |= ((* src++) >> shiftL);
* dst |= ((* src) & ((1 << (len - shiftR)) - 1)) << shiftR ;
}
}
/* Bitmask testcase code moved from here to
* storage/ndb/test/ndbapi/testBitfield.cpp
* to get coverage from automated testing
*/
|