Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
9a937a3b
Commit
9a937a3b
authored
Dec 08, 2004
by
joreland@mysql.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ndb - Fixed bitfields of upto 31 bits
parent
c97f6e24
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
146 additions
and
85 deletions
+146
-85
ndb/include/util/Bitmask.hpp
ndb/include/util/Bitmask.hpp
+18
-9
ndb/src/common/util/Bitmask.cpp
ndb/src/common/util/Bitmask.cpp
+128
-76
No files found.
ndb/include/util/Bitmask.hpp
View file @
9a937a3b
...
...
@@ -811,36 +811,45 @@ public:
};
inline
void
BitmaskImpl
::
getField
(
unsigned
size
,
const
Uint32
data
[],
BitmaskImpl
::
getField
(
unsigned
size
,
const
Uint32
src
[],
unsigned
pos
,
unsigned
len
,
Uint32
dst
[])
{
assert
(
len
>
0
);
assert
(
pos
+
len
<
(
size
<<
5
));
Uint32
word
=
pos
>>
5
;
src
+=
(
pos
>>
5
);
Uint32
offset
=
pos
&
31
;
dst
[
0
]
=
(
*
src
>>
offset
)
&
(
len
>=
32
?
~
0
:
(
1
<<
len
)
-
1
);
if
(
offset
+
len
<=
32
)
{
dst
[
0
]
=
(
data
[
word
]
>>
offset
)
&
((
1
<<
len
)
-
1
);
return
;
}
getFieldImpl
(
data
,
pos
,
len
,
dst
);
Uint32
used
=
(
32
-
offset
);
assert
(
len
>
used
);
getFieldImpl
(
src
+
1
,
used
&
31
,
len
-
used
,
dst
+
(
used
>>
5
));
}
inline
void
BitmaskImpl
::
setField
(
unsigned
size
,
Uint32
d
ata
[],
BitmaskImpl
::
setField
(
unsigned
size
,
Uint32
d
st
[],
unsigned
pos
,
unsigned
len
,
const
Uint32
src
[])
{
assert
(
len
>
0
);
assert
(
pos
+
len
<
(
size
<<
5
));
Uint32
word
=
pos
>>
5
;
dst
+=
(
pos
>>
5
);
Uint32
offset
=
pos
&
31
;
Uint32
mask
=
((
1
<<
len
)
-
1
)
<<
offset
;
data
[
word
]
=
(
data
[
word
]
&
~
mask
)
|
((
src
[
0
]
<<
offset
)
&
mask
);
Uint32
mask
=
(
len
>=
32
?
~
0
:
(
1
<<
len
)
-
1
)
<<
offset
;
*
dst
=
(
*
dst
&
~
mask
)
|
((
*
src
<<
offset
)
&
mask
);
if
(
offset
+
len
<=
32
)
{
return
;
}
setFieldImpl
(
data
,
pos
,
len
,
src
);
Uint32
used
=
(
32
-
offset
);
assert
(
len
>
used
);
setFieldImpl
(
dst
+
1
,
used
&
31
,
len
-
used
,
src
+
(
used
>>
5
));
}
...
...
ndb/src/common/util/Bitmask.cpp
View file @
9a937a3b
#include <Bitmask.hpp>
#include <NdbOut.hpp>
#ifndef __TEST_BITMASK__
void
BitmaskImpl
::
getFieldImpl
(
const
Uint32
data
[],
unsigned
pos
,
unsigned
l
,
Uint32
dst
[])
static
void
print
(
const
Uint32
src
[],
Uint32
len
,
Uint32
pos
=
0
)
{
Uint32
word
;
Uint32
offset
;
int
next_offset
,
i
;
int
len
=
l
;
for
(
i
=
0
,
next_offset
=
0
;
len
>
0
;
i
++
)
printf
(
"b'"
);
for
(
int
i
=
0
;
i
<
len
;
i
++
)
{
word
=
pos
>>
5
;
offset
=
pos
&
31
;
if
(
BitmaskImpl
::
get
((
pos
+
len
+
31
)
>>
5
,
src
,
i
+
pos
))
printf
(
"1"
);
else
printf
(
"0"
);
if
((
i
&
7
)
==
7
)
printf
(
" "
);
}
}
if
(
i
%
32
==
0
)
dst
[
i
/
32
]
=
0
;
#ifndef __TEST_BITMASK__
void
BitmaskImpl
::
getFieldImpl
(
const
Uint32
src
[],
unsigned
shift
,
unsigned
len
,
Uint32
dst
[])
{
assert
(
shift
<
32
);
if
(
!
next_offset
&&
(
offset
+
len
)
>
32
)
{
dst
[
i
/
32
]
=
(
data
[
word
]
>>
offset
)
&
((
1
<<
(
32
-
offset
))
-
1
);
next_offset
=
32
-
offset
;
}
else
if
(
len
<=
(
32
-
shift
))
{
*
dst
++
|=
((
*
src
)
&
((
1
<<
len
)
-
1
))
<<
shift
;
}
else
{
abort
();
while
(
len
>
32
)
{
dst
[
i
/
32
]
|=
((
data
[
word
]
>>
offset
)
&
((
1
<<
len
)
-
1
))
<<
next_offset
;
next_offset
=
0
;
*
dst
++
|=
(
*
src
)
<<
shift
;
*
dst
=
(
*
src
++
)
>>
(
32
-
shift
);
len
-=
32
;
}
if
(
len
<
32
-
offset
)
break
;
len
-=
32
-
offset
;
pos
+=
32
-
offset
;
}
}
void
BitmaskImpl
::
setFieldImpl
(
Uint32
d
ata
[],
unsigned
pos
,
unsigned
l
,
const
Uint32
src
[])
BitmaskImpl
::
setFieldImpl
(
Uint32
d
st
[],
unsigned
shift
,
unsigned
len
,
const
Uint32
src
[])
{
Uint32
word
;
Uint32
offset
;
assert
(
shift
<
32
)
;
Uint32
mask
;
int
i
=
0
,
stored
=
0
;
int
len
=
l
;
while
(
len
>
0
)
if
(
len
<
(
32
-
shift
))
{
ndbout_c
(
"len: %d"
,
len
);
word
=
pos
>>
5
;
offset
=
pos
&
31
;
if
(
offset
+
len
>
32
)
stored
=
32
-
offset
;
else
stored
=
len
;
mask
=
((
1
<<
stored
)
-
1
)
<<
(
i
+
offset
)
%
32
;
data
[
word
]
=
(
data
[
word
]
&
~
mask
)
|
((
src
[
i
/
32
]
<<
(
i
+
offset
)
%
32
)
&
mask
);
i
+=
stored
;
len
-=
32
-
offset
;
pos
+=
32
-
offset
;
mask
=
(
1
<<
len
)
-
1
;
*
dst
=
(
*
dst
&
~
mask
)
|
(((
*
src
++
)
>>
shift
)
&
mask
);
}
else
{
abort
();
}
}
...
...
@@ -71,7 +61,7 @@ BitmaskImpl::setFieldImpl(Uint32 data[],
#define DEBUG 0
#include <Vector.hpp>
void
do_test
(
int
bitmask_size
);
static
void
do_test
(
int
bitmask_size
);
int
main
(
int
argc
,
char
**
argv
)
...
...
@@ -91,30 +81,86 @@ struct Alloc
Vector
<
Uint32
>
data
;
};
void
require
(
bool
b
)
static
void
require
(
bool
b
)
{
if
(
!
b
)
abort
();
}
void
static
int
val_pos
=
0
;
static
int
val
[]
=
{
384
,
241
,
32
,
1
,
1
,
1
,
1
,
0
,
0
,
0
,
0
,
1
,
1
,
1
,
1
,
0
,
0
,
0
,
0
,
241
};
static
int
lrand
()
{
#if 0
return val[val_pos++];
#else
return
rand
();
#endif
}
static
void
rand
(
Uint32
dst
[],
Uint32
len
)
{
for
(
int
i
=
0
;
i
<
len
;
i
++
)
BitmaskImpl
::
set
((
len
+
31
)
>>
5
,
dst
,
i
,
(
lrand
()
%
1000
)
>
500
);
}
static
void
simple
(
int
pos
,
int
size
)
{
ndbout_c
(
"simple pos: %d size: %d"
,
pos
,
size
);
Vector
<
Uint32
>
_mask
;
Vector
<
Uint32
>
_src
;
Vector
<
Uint32
>
_dst
;
Uint32
sz32
=
(
size
+
pos
+
32
)
>>
5
;
const
Uint32
sz
=
4
*
sz32
;
Uint32
zero
=
0
;
_mask
.
fill
(
sz32
,
zero
);
_src
.
fill
(
sz32
,
zero
);
_dst
.
fill
(
sz32
,
zero
);
Uint32
*
src
=
_src
.
getBase
();
Uint32
*
dst
=
_dst
.
getBase
();
Uint32
*
mask
=
_mask
.
getBase
();
memset
(
src
,
0x0
,
sz
);
memset
(
dst
,
0x0
,
sz
);
memset
(
mask
,
0x0
,
sz
);
rand
(
src
,
size
);
BitmaskImpl
::
setField
(
sz32
,
mask
,
pos
,
size
,
src
);
BitmaskImpl
::
getField
(
sz32
,
mask
,
pos
,
size
,
dst
);
printf
(
"src: "
);
print
(
src
,
size
);
printf
(
"
\n
"
);
printf
(
"msk: "
);
print
(
mask
,
size
,
pos
);
printf
(
"
\n
"
);
printf
(
"dst: "
);
print
(
dst
,
size
);
printf
(
"
\n
"
);
require
(
memcmp
(
src
,
dst
,
sz
)
==
0
);
};
static
void
do_test
(
int
bitmask_size
)
{
#if 0
simple(rand() % 33, (rand() % 31)+1);
#else
Vector
<
Alloc
>
alloc_list
;
bitmask_size
=
(
bitmask_size
+
31
)
&
~
31
;
Uint32
sz32
=
(
bitmask_size
>>
5
);
Vector
<
Uint32
>
alloc_mask
;
Vector
<
Uint32
>
test_mask
;
Vector
<
Uint32
>
tmp
;
ndbout_c
(
"Testing bitmask of size %d"
,
bitmask_size
);
Uint32
zero
=
0
;
alloc_mask
.
fill
(
sz32
,
zero
);
test_mask
.
fill
(
sz32
,
zero
);
tmp
.
fill
(
sz32
,
zero
);
for
(
int
i
=
0
;
i
<
1
000
;
i
++
)
for
(
int
i
=
0
;
i
<
5
000
;
i
++
)
{
int
pos
=
rand
()
%
(
bitmask_size
-
1
);
Vector
<
Uint32
>
tmp
;
tmp
.
fill
(
sz32
,
zero
);
int
pos
=
lrand
()
%
(
bitmask_size
-
1
);
int
free
=
0
;
if
(
BitmaskImpl
::
get
(
sz32
,
alloc_mask
.
getBase
(),
pos
))
{
...
...
@@ -133,26 +179,26 @@ do_test(int bitmask_size)
break
;
}
}
if
(
DEBUG
)
ndbout_c
(
"freeing [ %d %d ]"
,
min
,
max
);
require
(
pos
>=
min
&&
pos
<
max
);
BitmaskImpl
::
getField
(
sz32
,
test_mask
.
getBase
(),
min
,
max
-
min
,
tmp
.
getBase
());
if
(
memcmp
(
tmp
.
getBase
(),
alloc_list
[
j
].
data
.
getBase
(),
((
max
-
min
)
+
31
)
>>
5
)
!=
0
)
if
(
DEBUG
)
{
printf
(
"mask: "
);
printf
(
"freeing [ %d %d ]"
,
min
,
max
);
printf
(
"- mask: "
);
for
(
size_t
k
=
0
;
k
<
(((
max
-
min
)
+
31
)
>>
5
);
k
++
)
printf
(
"%.8x "
,
tmp
.
getBase
()[
k
]);
printf
(
"save: "
);
size_t
k
;
Alloc
&
a
=
alloc_list
[
j
];
for
(
k
=
0
;
k
<
a
.
data
.
size
();
k
++
)
printf
(
"%.8x "
,
a
.
data
[
k
]);
printf
(
"
\n
"
);
printf
(
"field: "
);
for
(
k
=
0
;
k
<
(((
max
-
min
)
+
31
)
>>
5
);
k
++
)
printf
(
"%.8x "
,
tmp
.
getBase
()[
k
]);
printf
(
"
\n
"
);
}
int
bytes
=
(
max
-
min
+
7
)
>>
3
;
if
(
memcmp
(
tmp
.
getBase
(),
alloc_list
[
j
].
data
.
getBase
(),
bytes
)
!=
0
)
{
abort
();
}
while
(
min
<
max
)
...
...
@@ -161,31 +207,36 @@ do_test(int bitmask_size)
}
else
{
Vector
<
Uint32
>
tmp
;
tmp
.
fill
(
sz32
,
zero
);
// Bit was free
// 1) Check how much space is avaiable
// 2) Create new allocation of random size
// 3) Fill data with random data
// 2) Create new allocation of
l
random size
// 3) Fill data with
l
random data
// 4) Update alloc mask
while
(
pos
+
free
<
bitmask_size
&&
!
BitmaskImpl
::
get
(
sz32
,
alloc_mask
.
getBase
(),
pos
+
free
))
free
++
;
Uint32
sz
=
(
rand
()
%
free
);
sz
=
sz
?
sz
:
1
;
Uint32
sz
=
(
lrand
()
%
free
);
sz
=
sz
?
sz
:
1
;
sz
=
(
sz
>
31
)
?
31
:
sz
;
Alloc
a
;
a
.
pos
=
pos
;
a
.
size
=
sz
;
a
.
data
.
fill
(
sz
>>
5
,
zero
);
a
.
data
.
fill
(
((
sz
+
31
)
>>
5
)
-
1
,
zero
);
if
(
DEBUG
)
ndbout_c
(
"pos %d -> alloc [ %d %d ]"
,
pos
,
pos
,
pos
+
sz
);
printf
(
"pos %d -> alloc [ %d %d ]"
,
pos
,
pos
,
pos
+
sz
);
for
(
size_t
j
=
0
;
j
<
sz
;
j
++
)
{
BitmaskImpl
::
set
(
sz32
,
alloc_mask
.
getBase
(),
pos
+
j
);
if
((
rand
()
%
1000
)
>
500
)
if
((
l
rand
()
%
1000
)
>
500
)
BitmaskImpl
::
set
((
sz
+
31
)
>>
5
,
a
.
data
.
getBase
(),
j
);
}
if
(
DEBUG
)
{
printf
(
"mask: "
);
printf
(
"
-
mask: "
);
size_t
k
;
for
(
k
=
0
;
k
<
a
.
data
.
size
();
k
++
)
printf
(
"%.8x "
,
a
.
data
[
k
]);
...
...
@@ -196,6 +247,7 @@ do_test(int bitmask_size)
alloc_list
.
push_back
(
a
);
}
}
#endif
}
template
class
Vector
<
Alloc
>;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment