getGeomMissingUnusedIndex: use index if isBitSet() is false.

In getGeomMissingUnusedIndex(), use index if isBitSet() is false
instead of finding isUseBitSet() == true and cancel.  Added doc for
getGeomMissingUnusedIndex(). Renamed confusing names in bitfield.h.
pull/2/head
Tatsuhiro Tsujikawa 2011-08-24 22:59:00 +09:00
parent a081f651a1
commit b94bf3355b
3 changed files with 39 additions and 35 deletions

View File

@ -169,11 +169,11 @@ bool BitfieldMan::hasMissingPiece
bool BitfieldMan::getFirstMissingUnusedIndex(size_t& index) const bool BitfieldMan::getFirstMissingUnusedIndex(size_t& index) const
{ {
if(filterEnabled_) { if(filterEnabled_) {
return bitfield::getFirstMissingIndex return bitfield::getFirstSetBitIndex
(index, ~array(bitfield_)&~array(useBitfield_)&array(filterBitfield_), (index, ~array(bitfield_)&~array(useBitfield_)&array(filterBitfield_),
blocks_); blocks_);
} else { } else {
return bitfield::getFirstMissingIndex return bitfield::getFirstSetBitIndex
(index, ~array(bitfield_)&~array(useBitfield_), blocks_); (index, ~array(bitfield_)&~array(useBitfield_), blocks_);
} }
} }
@ -182,11 +182,11 @@ size_t BitfieldMan::getFirstNMissingUnusedIndex
(std::vector<size_t>& out, size_t n) const (std::vector<size_t>& out, size_t n) const
{ {
if(filterEnabled_) { if(filterEnabled_) {
return bitfield::getFirstNMissingIndex return bitfield::getFirstNSetBitIndex
(std::back_inserter(out), n, (std::back_inserter(out), n,
~array(bitfield_)&~array(useBitfield_)&array(filterBitfield_), blocks_); ~array(bitfield_)&~array(useBitfield_)&array(filterBitfield_), blocks_);
} else { } else {
return bitfield::getFirstNMissingIndex return bitfield::getFirstNSetBitIndex
(std::back_inserter(out), n, (std::back_inserter(out), n,
~array(bitfield_)&~array(useBitfield_), blocks_); ~array(bitfield_)&~array(useBitfield_), blocks_);
} }
@ -195,10 +195,10 @@ size_t BitfieldMan::getFirstNMissingUnusedIndex
bool BitfieldMan::getFirstMissingIndex(size_t& index) const bool BitfieldMan::getFirstMissingIndex(size_t& index) const
{ {
if(filterEnabled_) { if(filterEnabled_) {
return bitfield::getFirstMissingIndex return bitfield::getFirstSetBitIndex
(index, ~array(bitfield_)&array(filterBitfield_), blocks_); (index, ~array(bitfield_)&array(filterBitfield_), blocks_);
} else { } else {
return bitfield::getFirstMissingIndex(index, ~array(bitfield_), blocks_); return bitfield::getFirstSetBitIndex(index, ~array(bitfield_), blocks_);
} }
} }
@ -325,19 +325,17 @@ bool getGeomMissingUnusedIndex
double end = 1; double end = 1;
while(start+offsetIndex < blocks) { while(start+offsetIndex < blocks) {
index = blocks; index = blocks;
bool ok = false;
for(size_t i = start+offsetIndex, for(size_t i = start+offsetIndex,
eoi = std::min(blocks, static_cast<size_t>(end+offsetIndex)); eoi = std::min(blocks, static_cast<size_t>(end+offsetIndex));
i < eoi; ++i) { i < eoi; ++i) {
if(bitfield::test(useBitfield, blocks, i)) { if(bitfield::test(useBitfield, blocks, i)) {
ok = false;
break; break;
} else if(index == blocks && !bitfield::test(bitfield, blocks, i)) { } else if(!bitfield::test(bitfield, blocks, i)) {
ok = true;
index = i; index = i;
break;
} }
} }
if(ok) { if(index < blocks) {
return true; return true;
} else { } else {
start = end; start = end;

View File

@ -135,6 +135,20 @@ public:
const unsigned char* ignoreBitfield, const unsigned char* ignoreBitfield,
size_t ignoreBitfieldLength) const; size_t ignoreBitfieldLength) const;
// Stores missing bit index to index. This function first try to
// select smallest index starting offsetIndex in the order:
// offsetIndex, offsetIndex+base**1, offsetIndex+base**2, ... For
// each sequence [offsetIndex+base**i, offsetIndex+base**(i+1))
// (first sequence is special case and it is [offsetIndex,
// offsetIndex+base)) test isBitSet() and isUseBitSet() from the
// beginning of the sequence. If isBitSet(x) == false is found
// first, select x as index. If isUseBit(x) == true is found first
// or isBitSet(x) == false is not found, then quit search and go to
// the next sequence(increment i). If no index found in the above
// algorithm, call getSparseMissingUnusedIndex() and return its
// result.
//
// affected by filter
bool getGeomMissingUnusedIndex bool getGeomMissingUnusedIndex
(size_t& index, (size_t& index,
size_t minSplitSize, size_t minSplitSize,
@ -147,6 +161,8 @@ public:
// index of missing piece, considering minSplitSize. Set bits in // index of missing piece, considering minSplitSize. Set bits in
// ignoreBitfield are excluded. Returns true if such bit index is // ignoreBitfield are excluded. Returns true if such bit index is
// found. Otherwise returns false. // found. Otherwise returns false.
//
// affected by filter
bool getInorderMissingUnusedIndex bool getInorderMissingUnusedIndex
(size_t& index, (size_t& index,
size_t minSplitSize, size_t minSplitSize,

View File

@ -127,22 +127,17 @@ inline size_t countSetBit(const unsigned char* bitfield, size_t nbits)
void flipBit(unsigned char* data, size_t length, size_t bitIndex); void flipBit(unsigned char* data, size_t length, size_t bitIndex);
// Stores first missing bit index of bitfield to index. bitfield // Stores first set bit index of bitfield to index. bitfield contains
// contains nbits. Returns true if missing bit index is // nbits. Returns true if missing bit index is found. Otherwise
// found. Otherwise returns false. // returns false.
template<typename Array> template<typename Array>
bool getFirstMissingIndex bool getFirstSetBitIndex
(size_t& index, const Array& bitfield, size_t nbits) (size_t& index, const Array& bitfield, size_t nbits)
{ {
const size_t bitfieldLength = (nbits+7)/8; for(size_t i = 0; i < nbits; ++i) {
for(size_t i = 0; i < bitfieldLength; ++i) { if(bitfield::test(bitfield, nbits, i)) {
unsigned char mask = 128; index = i;
size_t tindex = i*8; return true;
for(size_t bi = 0; bi < 8 && tindex < nbits; ++bi, mask >>= 1, ++tindex) {
if(bitfield[i] & mask) {
index = tindex;
return true;
}
} }
} }
return false; return false;
@ -151,23 +146,18 @@ bool getFirstMissingIndex
// Appends first at most n set bit index in bitfield to out. bitfield // Appends first at most n set bit index in bitfield to out. bitfield
// contains nbits bits. Returns the number of appended bit indexes. // contains nbits bits. Returns the number of appended bit indexes.
template<typename Array, typename OutputIterator> template<typename Array, typename OutputIterator>
size_t getFirstNMissingIndex size_t getFirstNSetBitIndex
(OutputIterator out, size_t n, const Array& bitfield, size_t nbits) (OutputIterator out, size_t n, const Array& bitfield, size_t nbits)
{ {
if(n == 0) { if(n == 0) {
return 0; return 0;
} }
const size_t origN = n; const size_t origN = n;
const size_t bitfieldLength = (nbits+7)/8; for(size_t i = 0; i < nbits; ++i) {
for(size_t i = 0; i < bitfieldLength; ++i) { if(bitfield::test(bitfield, nbits, i)) {
unsigned char mask = 128; *out++ = i;
size_t tindex = i*8; if(--n == 0) {
for(size_t bi = 0; bi < 8 && tindex < nbits; ++bi, mask >>= 1, ++tindex) { break;
if(bitfield[i] & mask) {
*out++ = tindex;
if(--n == 0) {
return origN;
}
} }
} }
} }