Commit 4d27cab1 authored by joreland@mysql.com's avatar joreland@mysql.com

ndb - Fix arbitrary sized bitfields

parent 9a937a3b
...@@ -11,7 +11,7 @@ void print(const Uint32 src[], Uint32 len, Uint32 pos = 0) ...@@ -11,7 +11,7 @@ void print(const Uint32 src[], Uint32 len, Uint32 pos = 0)
printf("1"); printf("1");
else else
printf("0"); printf("0");
if((i & 7) == 7) if((i & 31) == 31)
printf(" "); printf(" ");
} }
} }
...@@ -19,42 +19,46 @@ void print(const Uint32 src[], Uint32 len, Uint32 pos = 0) ...@@ -19,42 +19,46 @@ void print(const Uint32 src[], Uint32 len, Uint32 pos = 0)
#ifndef __TEST_BITMASK__ #ifndef __TEST_BITMASK__
void void
BitmaskImpl::getFieldImpl(const Uint32 src[], BitmaskImpl::getFieldImpl(const Uint32 src[],
unsigned shift, unsigned len, Uint32 dst[]) unsigned shiftL, unsigned len, Uint32 dst[])
{ {
assert(shift < 32); assert(shiftL < 32);
if(len <= (32 - shift)) unsigned shiftR = 32 - shiftL;
{ while(len >= 32)
* dst++ |= ((* src) & ((1 << len) - 1)) << shift;
}
else
{ {
abort(); * dst++ |= (* src) << shiftL;
while(len > 32) * dst = shiftL ? (* src) >> shiftR : 0;
{ src++;
* dst++ |= (* src) << shift; len -= 32;
* dst = (* src++) >> (32 - shift);
len -= 32;
}
} }
* dst++ |= (* src) << shiftL;
* dst = shiftL ? ((* src) >> shiftR) & ((1 << len) - 1) : 0;
} }
void void
BitmaskImpl::setFieldImpl(Uint32 dst[], BitmaskImpl::setFieldImpl(Uint32 dst[],
unsigned shift, unsigned len, const Uint32 src[]) unsigned shiftL, unsigned len, const Uint32 src[])
{ {
assert(shift < 32); /**
*
* abcd ef00
* 00ab cdef
*/
assert(shiftL < 32);
unsigned shiftR = 32 - shiftL;
Uint32 mask; while(len >= 32)
if(len < (32 - shift))
{
mask = (1 << len) - 1;
* dst = (* dst & ~mask) | (((* src++) >> shift) & mask);
}
else
{ {
abort(); * dst = (* src++) >> shiftL;
* dst++ |= shiftL ? (* src) << shiftR : 0;
len -= 32;
} }
Uint32 mask = ((1 << len) -1);
* dst = (* dst & ~mask);
* dst |= ((* src++) >> shiftL) & mask;
* dst |= shiftL ? ((* src) << shiftR) & mask : 0;
} }
#else #else
...@@ -86,6 +90,19 @@ static void require(bool b) ...@@ -86,6 +90,19 @@ static void require(bool b)
if(!b) abort(); if(!b) abort();
} }
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_pos = 0;
static int val[] = { 384, 241, 32, static int val[] = { 384, 241, 32,
1,1,1,1, 0,0,0,0, 1,1,1,1, 0,0,0,0, 1,1,1,1, 0,0,0,0, 1,1,1,1, 0,0,0,0,
...@@ -128,21 +145,21 @@ void simple(int pos, int size) ...@@ -128,21 +145,21 @@ void simple(int pos, int size)
memset(src, 0x0, sz); memset(src, 0x0, sz);
memset(dst, 0x0, sz); memset(dst, 0x0, sz);
memset(mask, 0x0, sz); memset(mask, 0xFF, sz);
rand(src, size); rand(src, size);
BitmaskImpl::setField(sz32, mask, pos, size, src); BitmaskImpl::setField(sz32, mask, pos, size, src);
BitmaskImpl::getField(sz32, mask, pos, size, dst); BitmaskImpl::getField(sz32, mask, pos, size, dst);
printf("src: "); print(src, size); printf("\n"); printf("src: "); print(src, size); printf("\n");
printf("msk: "); print(mask, size, pos); printf("\n"); printf("msk: "); print(mask, sz32 << 5); printf("\n");
printf("dst: "); print(dst, size); printf("\n"); printf("dst: "); print(dst, size); printf("\n");
require(memcmp(src, dst, sz) == 0); require(cmp(src, dst, size));
}; };
static void static void
do_test(int bitmask_size) do_test(int bitmask_size)
{ {
#if 0 #if 0
simple(rand() % 33, (rand() % 31)+1); simple(rand() % 33, (rand() % 63)+1);
#else #else
Vector<Alloc> alloc_list; Vector<Alloc> alloc_list;
bitmask_size = (bitmask_size + 31) & ~31; bitmask_size = (bitmask_size + 31) & ~31;
...@@ -186,10 +203,9 @@ do_test(int bitmask_size) ...@@ -186,10 +203,9 @@ do_test(int bitmask_size)
{ {
printf("freeing [ %d %d ]", min, max); printf("freeing [ %d %d ]", min, max);
printf("- mask: "); printf("- mask: ");
for(size_t k = 0; k<(((max - min)+31)>>5); k++) print(tmp.getBase(), max - min);
printf("%.8x ", tmp.getBase()[k]);
printf(" save: ");
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++)
...@@ -197,7 +213,7 @@ do_test(int bitmask_size) ...@@ -197,7 +213,7 @@ do_test(int bitmask_size)
printf("\n"); printf("\n");
} }
int bytes = (max - min + 7) >> 3; int bytes = (max - min + 7) >> 3;
if(memcmp(tmp.getBase(), alloc_list[j].data.getBase(), bytes) != 0) if(!cmp(tmp.getBase(), alloc_list[j].data.getBase(), max - min))
{ {
abort(); abort();
} }
...@@ -221,7 +237,6 @@ do_test(int bitmask_size) ...@@ -221,7 +237,6 @@ do_test(int bitmask_size)
Uint32 sz = (lrand() % free); Uint32 sz = (lrand() % free);
sz = sz ? sz : 1; 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;
...@@ -237,9 +252,7 @@ do_test(int bitmask_size) ...@@ -237,9 +252,7 @@ do_test(int bitmask_size)
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,
......
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