Commit b8970d99 authored by unknown's avatar unknown

Merge joreland@bk-internal.mysql.com:/home/bk/mysql-5.0-ndb

into mysql.com:/home/jonas/src/mysql-5.0-ndb

parents 9be0b610 377aedfb
...@@ -811,36 +811,45 @@ public: ...@@ -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));
} }
......
#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 & 31) == 31)
next_offset = 0; printf(" ");
}
if(len < 32-offset)
break;
len-=32-offset;
pos+=32-offset;
} }
} }
#ifndef __TEST_BITMASK__
void void
BitmaskImpl::setFieldImpl(Uint32 data[], BitmaskImpl::getFieldImpl(const Uint32 src[],
unsigned pos, unsigned l, const Uint32 src[]) unsigned shiftL, unsigned len, Uint32 dst[])
{ {
Uint32 word; assert(shiftL < 32);
Uint32 offset;
Uint32 mask; unsigned shiftR = 32 - shiftL;
int i=0,stored=0; while(len >= 32)
int len= l; {
* dst++ |= (* src) << shiftL;
* dst = shiftL ? (* src) >> shiftR : 0;
src++;
len -= 32;
}
* dst++ |= (* src) << shiftL;
* dst = shiftL ? ((* src) >> shiftR) & ((1 << len) - 1) : 0;
}
while(len>0) void
BitmaskImpl::setFieldImpl(Uint32 dst[],
unsigned shiftL, unsigned len, const Uint32 src[])
{
/**
*
* abcd ef00
* 00ab cdef
*/
assert(shiftL < 32);
unsigned shiftR = 32 - shiftL;
while(len >= 32)
{ {
ndbout_c("len: %d", len); * dst = (* src++) >> shiftL;
word = pos >> 5; * dst++ |= shiftL ? (* src) << shiftR : 0;
offset = pos & 31; len -= 32;
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;
} }
Uint32 mask = ((1 << len) -1);
* dst = (* dst & ~mask);
* dst |= ((* src++) >> shiftL) & mask;
* dst |= shiftL ? ((* src) << shiftR) & mask : 0;
} }
#else #else
#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 +85,99 @@ struct Alloc ...@@ -91,30 +85,99 @@ 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
bool cmp(const Uint32 b1[], const Uint32 b2[], Uint32 len)
{
Uint32 sz32 = (len + 31) >> 5;
for(int i = 0; i<len; i++)
{
if(BitmaskImpl::get(sz32, b1, i) ^ BitmaskImpl::get(sz32, b2, i))
return false;
}
return true;
}
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, 0xFF, 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, sz32 << 5); printf("\n");
printf("dst: "); print(dst, size); printf("\n");
require(cmp(src, dst, size));
};
static void
do_test(int bitmask_size) do_test(int bitmask_size)
{ {
#if 0
simple(rand() % 33, (rand() % 63)+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 +196,25 @@ do_test(int bitmask_size) ...@@ -133,26 +196,25 @@ 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: ");
print(tmp.getBase(), max - min);
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(!cmp(tmp.getBase(), alloc_list[j].data.getBase(), max - min))
printf("%.8x ", tmp.getBase()[k]); {
printf("\n");
abort(); abort();
} }
while(min < max) while(min < max)
...@@ -161,34 +223,36 @@ do_test(int bitmask_size) ...@@ -161,34 +223,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;
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; print(a.data.getBase(), sz);
for(k = 0; k<a.data.size(); k++)
printf("%.8x ", a.data[k]);
printf("\n"); printf("\n");
} }
BitmaskImpl::setField(sz32, test_mask.getBase(), pos, sz, BitmaskImpl::setField(sz32, test_mask.getBase(), pos, sz,
...@@ -196,6 +260,7 @@ do_test(int bitmask_size) ...@@ -196,6 +260,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>;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment