瀏覽代碼

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.
Tatsuhiro Tsujikawa 14 年之前
父節點
當前提交
b94bf3355b
共有 3 個文件被更改,包括 39 次插入35 次删除
  1. 9 11
      src/BitfieldMan.cc
  2. 16 0
      src/BitfieldMan.h
  3. 14 24
      src/bitfield.h

+ 9 - 11
src/BitfieldMan.cc

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

+ 16 - 0
src/BitfieldMan.h

@@ -135,6 +135,20 @@ public:
    const unsigned char* ignoreBitfield,
    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
   (size_t& index,
    size_t minSplitSize,
@@ -147,6 +161,8 @@ public:
   // index of missing piece, considering minSplitSize.  Set bits in
   // ignoreBitfield are excluded. Returns true if such bit index is
   // found. Otherwise returns false.
+  //
+  // affected by filter
   bool getInorderMissingUnusedIndex
   (size_t& index,
    size_t minSplitSize,

+ 14 - 24
src/bitfield.h

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