mirror of
https://github.com/MariaDB/server.git
synced 2025-11-16 20:23:18 +03:00
ndb - Fixed bitfields of upto 31 bits
This commit is contained in:
@@ -811,36 +811,45 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
BitmaskImpl::getField(unsigned size, const Uint32 data[],
|
BitmaskImpl::getField(unsigned size, const Uint32 src[],
|
||||||
unsigned pos, unsigned len, Uint32 dst[])
|
unsigned pos, unsigned len, Uint32 dst[])
|
||||||
{
|
{
|
||||||
assert(len > 0);
|
assert(len > 0);
|
||||||
assert(pos + len < (size << 5));
|
assert(pos + len < (size << 5));
|
||||||
Uint32 word = pos >> 5;
|
|
||||||
|
src += (pos >> 5);
|
||||||
Uint32 offset = pos & 31;
|
Uint32 offset = pos & 31;
|
||||||
|
dst[0] = (* src >> offset) & (len >= 32 ? ~0 : (1 << len) - 1);
|
||||||
|
|
||||||
if(offset + len <= 32)
|
if(offset + len <= 32)
|
||||||
{
|
{
|
||||||
dst[0] = (data[word] >> offset) & ((1 << len) - 1);
|
|
||||||
return;
|
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
|
inline void
|
||||||
BitmaskImpl::setField(unsigned size, Uint32 data[],
|
BitmaskImpl::setField(unsigned size, Uint32 dst[],
|
||||||
unsigned pos, unsigned len, const Uint32 src[])
|
unsigned pos, unsigned len, const Uint32 src[])
|
||||||
{
|
{
|
||||||
assert(len > 0);
|
assert(len > 0);
|
||||||
assert(pos + len < (size << 5));
|
assert(pos + len < (size << 5));
|
||||||
Uint32 word = pos >> 5;
|
|
||||||
|
dst += (pos >> 5);
|
||||||
Uint32 offset = pos & 31;
|
Uint32 offset = pos & 31;
|
||||||
Uint32 mask = ((1 << len) - 1) << offset;
|
Uint32 mask = (len >= 32 ? ~0 : (1 << len) - 1) << offset;
|
||||||
data[word] = (data[word] & ~mask) | ((src[0] << offset) & mask);
|
|
||||||
|
* dst = (* dst & ~mask) | ((*src << offset) & mask);
|
||||||
|
|
||||||
if(offset + len <= 32)
|
if(offset + len <= 32)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setFieldImpl(data, pos, len, src);
|
Uint32 used = (32 - offset);
|
||||||
|
assert(len > used);
|
||||||
|
setFieldImpl(dst+1, used & 31, len-used, src+(used >> 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,69 +1,59 @@
|
|||||||
#include <Bitmask.hpp>
|
#include <Bitmask.hpp>
|
||||||
#include <NdbOut.hpp>
|
#include <NdbOut.hpp>
|
||||||
|
|
||||||
#ifndef __TEST_BITMASK__
|
static
|
||||||
void
|
void print(const Uint32 src[], Uint32 len, Uint32 pos = 0)
|
||||||
BitmaskImpl::getFieldImpl(const Uint32 data[],
|
|
||||||
unsigned pos, unsigned l, Uint32 dst[])
|
|
||||||
{
|
{
|
||||||
Uint32 word;
|
printf("b'");
|
||||||
Uint32 offset;
|
for(int i = 0; i<len; i++)
|
||||||
int next_offset,i;
|
|
||||||
int len= l;
|
|
||||||
for(i=0,next_offset=0;len >0;i++)
|
|
||||||
{
|
{
|
||||||
word = pos >> 5;
|
if(BitmaskImpl::get((pos + len + 31) >> 5, src, i+pos))
|
||||||
offset = pos & 31;
|
printf("1");
|
||||||
|
|
||||||
if(i%32==0)
|
|
||||||
dst[i/32]=0;
|
|
||||||
|
|
||||||
if(!next_offset && (offset+len) > 32)
|
|
||||||
{
|
|
||||||
dst[i/32] = (data[word] >> offset) & ((1 << (32-offset)) - 1);
|
|
||||||
next_offset = 32-offset;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
printf("0");
|
||||||
dst[i/32]|= ((data[word] >> offset) & ((1 << len) - 1)) << next_offset;
|
if((i & 7) == 7)
|
||||||
next_offset = 0;
|
printf(" ");
|
||||||
}
|
|
||||||
|
|
||||||
if(len < 32-offset)
|
|
||||||
break;
|
|
||||||
|
|
||||||
len-=32-offset;
|
|
||||||
pos+=32-offset;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
BitmaskImpl::setFieldImpl(Uint32 data[],
|
|
||||||
unsigned pos, unsigned l, const Uint32 src[])
|
|
||||||
{
|
|
||||||
Uint32 word;
|
|
||||||
Uint32 offset;
|
|
||||||
Uint32 mask;
|
|
||||||
int i=0,stored=0;
|
|
||||||
int len= l;
|
|
||||||
|
|
||||||
while(len>0)
|
#ifndef __TEST_BITMASK__
|
||||||
|
void
|
||||||
|
BitmaskImpl::getFieldImpl(const Uint32 src[],
|
||||||
|
unsigned shift, unsigned len, Uint32 dst[])
|
||||||
|
{
|
||||||
|
assert(shift < 32);
|
||||||
|
|
||||||
|
if(len <= (32 - shift))
|
||||||
{
|
{
|
||||||
ndbout_c("len: %d", len);
|
* dst++ |= ((* src) & ((1 << len) - 1)) << shift;
|
||||||
word = pos >> 5;
|
}
|
||||||
offset = pos & 31;
|
else
|
||||||
|
{
|
||||||
if(offset+len > 32)
|
abort();
|
||||||
stored = 32-offset;
|
while(len > 32)
|
||||||
else
|
{
|
||||||
stored = len;
|
* dst++ |= (* src) << shift;
|
||||||
|
* dst = (* src++) >> (32 - shift);
|
||||||
mask = ((1 << stored) - 1) << (i+offset)%32;
|
len -= 32;
|
||||||
data[word] = (data[word] & ~mask) | ((src[i/32] << (i+offset)%32) & mask);
|
}
|
||||||
|
}
|
||||||
i+=stored;
|
}
|
||||||
len-=32-offset;
|
|
||||||
pos+=32-offset;
|
void
|
||||||
|
BitmaskImpl::setFieldImpl(Uint32 dst[],
|
||||||
|
unsigned shift, unsigned len, const Uint32 src[])
|
||||||
|
{
|
||||||
|
assert(shift < 32);
|
||||||
|
|
||||||
|
Uint32 mask;
|
||||||
|
if(len < (32 - shift))
|
||||||
|
{
|
||||||
|
mask = (1 << len) - 1;
|
||||||
|
* dst = (* dst & ~mask) | (((* src++) >> shift) & mask);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +61,7 @@ BitmaskImpl::setFieldImpl(Uint32 data[],
|
|||||||
|
|
||||||
#define DEBUG 0
|
#define DEBUG 0
|
||||||
#include <Vector.hpp>
|
#include <Vector.hpp>
|
||||||
void do_test(int bitmask_size);
|
static void do_test(int bitmask_size);
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char** argv)
|
main(int argc, char** argv)
|
||||||
@@ -91,30 +81,86 @@ struct Alloc
|
|||||||
Vector<Uint32> data;
|
Vector<Uint32> data;
|
||||||
};
|
};
|
||||||
|
|
||||||
void require(bool b)
|
static void require(bool b)
|
||||||
{
|
{
|
||||||
if(!b) abort();
|
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)
|
do_test(int bitmask_size)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
|
simple(rand() % 33, (rand() % 31)+1);
|
||||||
|
#else
|
||||||
Vector<Alloc> alloc_list;
|
Vector<Alloc> alloc_list;
|
||||||
bitmask_size = (bitmask_size + 31) & ~31;
|
bitmask_size = (bitmask_size + 31) & ~31;
|
||||||
Uint32 sz32 = (bitmask_size >> 5);
|
Uint32 sz32 = (bitmask_size >> 5);
|
||||||
Vector<Uint32> alloc_mask;
|
Vector<Uint32> alloc_mask;
|
||||||
Vector<Uint32> test_mask;
|
Vector<Uint32> test_mask;
|
||||||
Vector<Uint32> tmp;
|
|
||||||
|
|
||||||
ndbout_c("Testing bitmask of size %d", bitmask_size);
|
ndbout_c("Testing bitmask of size %d", bitmask_size);
|
||||||
Uint32 zero = 0;
|
Uint32 zero = 0;
|
||||||
alloc_mask.fill(sz32, zero);
|
alloc_mask.fill(sz32, zero);
|
||||||
test_mask.fill(sz32, zero);
|
test_mask.fill(sz32, zero);
|
||||||
tmp.fill(sz32, zero);
|
|
||||||
|
|
||||||
for(int i = 0; i<1000; i++)
|
for(int i = 0; i<5000; i++)
|
||||||
{
|
{
|
||||||
int pos = rand() % (bitmask_size - 1);
|
Vector<Uint32> tmp;
|
||||||
|
tmp.fill(sz32, zero);
|
||||||
|
|
||||||
|
int pos = lrand() % (bitmask_size - 1);
|
||||||
int free = 0;
|
int free = 0;
|
||||||
if(BitmaskImpl::get(sz32, alloc_mask.getBase(), pos))
|
if(BitmaskImpl::get(sz32, alloc_mask.getBase(), pos))
|
||||||
{
|
{
|
||||||
@@ -133,26 +179,26 @@ do_test(int bitmask_size)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(DEBUG)
|
|
||||||
ndbout_c("freeing [ %d %d ]", min, max);
|
|
||||||
|
|
||||||
require(pos >= min && pos < max);
|
require(pos >= min && pos < max);
|
||||||
BitmaskImpl::getField(sz32, test_mask.getBase(), min, max-min,
|
BitmaskImpl::getField(sz32, test_mask.getBase(), min, max-min,
|
||||||
tmp.getBase());
|
tmp.getBase());
|
||||||
if(memcmp(tmp.getBase(), alloc_list[j].data.getBase(),
|
if(DEBUG)
|
||||||
((max - min) + 31) >> 5) != 0)
|
|
||||||
{
|
{
|
||||||
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;
|
size_t k;
|
||||||
Alloc& a = alloc_list[j];
|
Alloc& a = alloc_list[j];
|
||||||
for(k = 0; k<a.data.size(); k++)
|
for(k = 0; k<a.data.size(); k++)
|
||||||
printf("%.8x ", a.data[k]);
|
printf("%.8x ", a.data[k]);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
}
|
||||||
printf("field: ");
|
int bytes = (max - min + 7) >> 3;
|
||||||
for(k = 0; k<(((max - min)+31)>>5); k++)
|
if(memcmp(tmp.getBase(), alloc_list[j].data.getBase(), bytes) != 0)
|
||||||
printf("%.8x ", tmp.getBase()[k]);
|
{
|
||||||
printf("\n");
|
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
while(min < max)
|
while(min < max)
|
||||||
@@ -161,31 +207,36 @@ do_test(int bitmask_size)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Vector<Uint32> tmp;
|
||||||
|
tmp.fill(sz32, zero);
|
||||||
|
|
||||||
// Bit was free
|
// Bit was free
|
||||||
// 1) Check how much space is avaiable
|
// 1) Check how much space is avaiable
|
||||||
// 2) Create new allocation of random size
|
// 2) Create new allocation of lrandom size
|
||||||
// 3) Fill data with random data
|
// 3) Fill data with lrandom data
|
||||||
// 4) Update alloc mask
|
// 4) Update alloc mask
|
||||||
while(pos+free < bitmask_size &&
|
while(pos+free < bitmask_size &&
|
||||||
!BitmaskImpl::get(sz32, alloc_mask.getBase(), pos+free))
|
!BitmaskImpl::get(sz32, alloc_mask.getBase(), pos+free))
|
||||||
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;
|
Alloc a;
|
||||||
a.pos = pos;
|
a.pos = pos;
|
||||||
a.size = sz;
|
a.size = sz;
|
||||||
a.data.fill(sz >> 5, zero);
|
a.data.fill(((sz+31)>> 5)-1, zero);
|
||||||
if(DEBUG)
|
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++)
|
for(size_t j = 0; j<sz; j++)
|
||||||
{
|
{
|
||||||
BitmaskImpl::set(sz32, alloc_mask.getBase(), pos+j);
|
BitmaskImpl::set(sz32, alloc_mask.getBase(), pos+j);
|
||||||
if((rand() % 1000) > 500)
|
if((lrand() % 1000) > 500)
|
||||||
BitmaskImpl::set((sz + 31) >> 5, a.data.getBase(), j);
|
BitmaskImpl::set((sz + 31) >> 5, a.data.getBase(), j);
|
||||||
}
|
}
|
||||||
if(DEBUG)
|
if(DEBUG)
|
||||||
{
|
{
|
||||||
printf("mask: ");
|
printf("- mask: ");
|
||||||
size_t k;
|
size_t k;
|
||||||
for(k = 0; k<a.data.size(); k++)
|
for(k = 0; k<a.data.size(); k++)
|
||||||
printf("%.8x ", a.data[k]);
|
printf("%.8x ", a.data[k]);
|
||||||
@@ -196,6 +247,7 @@ do_test(int bitmask_size)
|
|||||||
alloc_list.push_back(a);
|
alloc_list.push_back(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template class Vector<Alloc>;
|
template class Vector<Alloc>;
|
||||||
|
|||||||
Reference in New Issue
Block a user