⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bitmask.cpp

📁 MySQL数据库开发源码 值得一看哦
💻 CPP
字号:
#include <Bitmask.hpp>#include <NdbOut.hpp>staticvoid print(const Uint32 src[], Uint32 len, Uint32 pos = 0){  printf("b'");  for(unsigned i = 0; i<len; i++)  {    if(BitmaskImpl::get((pos + len + 31) >> 5, src, i+pos))      printf("1");    else      printf("0");    if((i & 31) == 31)      printf(" ");  }}#ifndef __TEST_BITMASK__voidBitmaskImpl::getFieldImpl(const Uint32 src[],			  unsigned shiftL, unsigned len, Uint32 dst[]){  assert(shiftL < 32);  unsigned shiftR = 32 - shiftL;  unsigned undefined = shiftL ? ~0 : 0;  * dst = shiftL ? * dst : 0;    while(len >= 32)  {    * dst++ |= (* src) << shiftL;    * dst = ((* src++) >> shiftR) & undefined;    len -= 32;  }    if(len < shiftR)  {    * dst |= ((* src) & ((1 << len) - 1)) << shiftL;  }  else  {    * dst++ |= ((* src) << shiftL);    * dst = ((* src) >> shiftR) & ((1 << (len - shiftR)) - 1) & undefined;  }}voidBitmaskImpl::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;  }    Uint32 mask = ((1 << len) -1);  * dst = (* dst & ~mask);  if(len < shiftR)  {    * dst |= ((* src++) >> shiftL) & mask;  }  else  {    * dst |= ((* src++) >> shiftL);    * dst |= ((* src) & ((1 << (len - shiftR)) - 1)) << shiftR ;  }}#else#define DEBUG 0#include <Vector.hpp>static void do_test(int bitmask_size);intmain(int argc, char** argv){  int loops = argc > 1 ? atoi(argv[1]) : 1000;  int max_size = argc > 2 ? atoi(argv[2]) : 1000;    for(int i = 0; i<loops; i++)    do_test(1 + (rand() % max_size));}struct Alloc{  Uint32 pos;  Uint32 size;  Vector<Uint32> data;};static void require(bool b){  if(!b) abort();}staticbool 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}staticvoid rand(Uint32 dst[], Uint32 len){  for(int i = 0; i<len; i++)    BitmaskImpl::set((len + 31) >> 5, dst, i, (lrand() % 1000) > 500);}staticvoid 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+1, zero);  _src.fill(sz32+1, zero);  _dst.fill(sz32+1, 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+31); printf("\n");  printf("msk: "); print(mask, (sz32 << 5) + 31); printf("\n");  printf("dst: "); print(dst, size+31); printf("\n");  require(cmp(src, dst, size+31));};staticvoid simple2(int size, int loops){  ndbout_c("simple2 %d - ", size);  Vector<Uint32> _mask;  Vector<Uint32> _src;  Vector<Uint32> _dst;  Uint32 sz32 = (size + 32) >> 5;  Uint32 sz = sz32 << 2;    Uint32 zero = 0;  _mask.fill(sz32+1, zero);  _src.fill(sz32+1, zero);  _dst.fill(sz32+1, zero);  Uint32 * src = _src.getBase();  Uint32 * dst = _dst.getBase();  Uint32 * mask = _mask.getBase();  Vector<Uint32> save;  for(int i = 0; i<loops; i++)  {    memset(mask, 0xFF, sz);    memset(dst, 0xFF, sz);    int len;    int pos = 0;    while(pos+1 < size)    {      memset(src, 0xFF, sz);      while(!(len = rand() % (size - pos)));      BitmaskImpl::setField(sz32, mask, pos, len, src);      if(memcmp(dst, mask, sz))      {	ndbout_c("pos: %d len: %d", pos, len);	print(mask, size);	abort();      }      printf("[ %d %d ]", pos, len);      save.push_back(pos);      save.push_back(len);      pos += len;    }    for(int j = 0; j<save.size(); )    {      pos = save[j++];      len = save[j++];      memset(src, 0xFF, sz);      BitmaskImpl::getField(sz32, mask, pos, len, src);      if(memcmp(dst, src, sz))      {	ndbout_c("pos: %d len: %d", pos, len);	printf("src: "); print(src, size); printf("\n");	printf("dst: "); print(dst, size); printf("\n");	printf("msk: "); print(mask, size); printf("\n");	abort();      }    }    ndbout_c("");  }}static void do_test(int bitmask_size){#if 1  simple(rand() % 33, (rand() % 63)+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;    ndbout_c("Testing bitmask of size %d", bitmask_size);  Uint32 zero = 0;  alloc_mask.fill(sz32, zero);  test_mask.fill(sz32, zero);    for(int i = 0; i<5000; i++)  {    Vector<Uint32> tmp;    tmp.fill(sz32, zero);    int pos = lrand() % (bitmask_size - 1);    int free = 0;    if(BitmaskImpl::get(sz32, alloc_mask.getBase(), pos))    {      // Bit was allocated      // 1) Look up allocation      // 2) Check data      // 3) free it      size_t j;      int min, max;      for(j = 0; j<alloc_list.size(); j++)      {	min = alloc_list[j].pos;	max = min + alloc_list[j].size;	if(pos >= min && pos < max)	{	  break;	}      }      require(pos >= min && pos < max);      BitmaskImpl::getField(sz32, test_mask.getBase(), min, max-min, 			    tmp.getBase());      if(DEBUG)      {	printf("freeing [ %d %d ]", min, max);	printf("- mask: ");	print(tmp.getBase(), max - min);		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");      }      int bytes = (max - min + 7) >> 3;      if(!cmp(tmp.getBase(), alloc_list[j].data.getBase(), max - min))      {	abort();      }      while(min < max)	BitmaskImpl::clear(sz32, alloc_mask.getBase(), min++);      alloc_list.erase(j);    }    else    {      Vector<Uint32> tmp;      tmp.fill(sz32, zero);            // Bit was free      // 1) Check how much space is avaiable      // 2) Create new allocation of lrandom size      // 3) Fill data with lrandom data      // 4) Update alloc mask      while(pos+free < bitmask_size && 	    !BitmaskImpl::get(sz32, alloc_mask.getBase(), pos+free))	free++;      Uint32 sz = 	(free <= 64 && ((lrand() % 100) > 80)) ? free : (lrand() % free);       sz = sz ? sz : 1;      sz = pos + sz == bitmask_size ? sz - 1 : sz;      Alloc a;      a.pos = pos;      a.size = sz;      a.data.fill(((sz+31)>> 5)-1, zero);      if(DEBUG)	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((lrand() % 1000) > 500)	  BitmaskImpl::set((sz + 31) >> 5, a.data.getBase(), j);      }      if(DEBUG)      {	printf("- mask: ");	print(a.data.getBase(), sz);	printf("\n");      }      BitmaskImpl::setField(sz32, test_mask.getBase(), pos, sz, 			    a.data.getBase());      alloc_list.push_back(a);    }  }#endif}template class Vector<Alloc>;template class Vector<Uint32>;#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -