예제 #1
0
  private WAHBitSet genericOp(OpType op, WAHBitSet other) {
    WAHBitSet ret = new WAHBitSet();

    // ensure that they have the same bit length.
    if (this.numBits() < other.numBits()) {
      this.setBit(other.numBits() - 1, 0);
    } else if (this.numBits() > other.numBits()) {
      other.setBit(numBits() - 1, 0);
    }

    if (vec.size() > 0) {
      run xrun = new run(vec), yrun = new run(other.vec);
      xrun.decode();
      yrun.decode();
      do {
        if (xrun.nWords == 0) {
          xrun.inc();
          xrun.decode();
        }

        if (yrun.nWords == 0) {
          yrun.inc();
          yrun.decode();
        }

        if (xrun.isFill()) {
          if (yrun.isFill()) {
            int nWords = Math.min(xrun.nWords, yrun.nWords);
            ret.appendFill(nWords, getOpResult(op, xrun.fillWord, yrun.fillWord));
            xrun.nWords -= nWords;
            yrun.nWords -= nWords;
          } else {
            ret.active.val = getOpResult(op, xrun.fillWord, yrun.get());
            ret.appendLiteral();
            --xrun.nWords;
            yrun.nWords = 0;
          }
        } else if (yrun.isFill()) {
          ret.active.val = getOpResult(op, yrun.fillWord, xrun.get());
          ret.appendLiteral();
          yrun.nWords--;
          xrun.nWords = 0;
        } else {
          ret.active.val = getOpResult(op, xrun.get(), yrun.get());
          ret.appendLiteral();
          yrun.nWords = 0;
          xrun.nWords = 0;
        }

      } while (!(xrun.end() && yrun.end()));
    }
    ret.active.val = getOpResult(op, this.active.val, other.active.val);
    ret.active.nbits = this.active.nbits;

    ret.doCount();
    return ret;
  }
예제 #2
0
 private void appendWord(int w) {
   if (RUN_UNTESTED_CODE) {
     int nb1, nb2;
     int cps = (w >>> MAXBITS);
     nset = 0;
     if (active.nbits != 0) { // active contains some uncompressed bits
       int w1;
       nb1 = active.nbits;
       nb2 = MAXBITS - active.nbits;
       active.val <<= nb2;
       if (cps != 0) { // incoming bits are comporessed
         boolean b2 = isOneFill(w);
         if (b2) {
           w1 = (1 << nb2) - 1;
           active.val |= w1;
         }
         appendLiteral();
         nb2 = (w & MAXCNT) - 1;
         if (nb2 > 1) { // append a counter
           appendCounter(b2 ? 1 : 0, nb2);
         } else if (nb2 == 1) {
           if (b2) active.val = ALLONES;
           appendLiteral();
         }
         active.nbits = nb1;
         active.val = ((1 << nb1) - 1) * (b2 ? 1 : 0);
       } else { // incoming bits are not compressed
         w1 = (w >>> nb1);
         active.val |= w1;
         appendLiteral();
         w1 = (1 << nb1) - 1;
         active.val = (w & w1);
         active.nbits = nb1;
       }
     } // end of the case where there are active bits
     else if (cps != 0) { // no active bit
       int b2 = (isOneFill(w) ? 1 : 0);
       nb2 = (w & MAXCNT);
       if (nb2 > 1) appendCounter(b2, nb2);
       else if (nb2 == 1) {
         if (b2 != 0) active.val = ALLONES;
         appendLiteral();
       }
     } else { // no active bits
       // new word is a raw bit pattern, simply add the word
       active.val = w;
       appendLiteral();
     }
   } else {
     throw new AssertionError("Untested code detected, would rather die than run this");
   }
 }
예제 #3
0
 private void appendFill(int nWords, int v) {
   if (vec.isEmpty()) {
     if (v == 0) {
       vec.add(HEADER0 | nWords);
     } else {
       vec.add(HEADER1 | nWords);
     }
   } else if (nWords > 1) {
     int back = getBack();
     if (v == 0) {
       if (isZeroFill(back)) {
         setBack(back + nWords);
       } else {
         vec.add(HEADER0 | nWords);
       }
     } else if (isOneFill(back)) {
       setBack(back + nWords);
     } else {
       vec.add(HEADER1 | nWords);
     }
   } else {
     active.val = v != 0 ? ALLONES : 0;
     appendLiteral();
   }
 }
예제 #4
0
  private void setBit(int ind, int val) {
    assert val == 0 || val == 1;

    if (ind >= numBits()) {
      int diff = ind - numBits() + 1;
      if (active.nbits > 0) {
        if (ind + 1 >= nbits + MAXBITS) {
          diff -= MAXBITS - active.nbits;
          active.val <<= (MAXBITS - active.nbits);
          if (diff == 0) active.val += (val != 0 ? 1 : 0);
          appendLiteral();
        } else {
          active.nbits += diff;
          active.val <<= diff;
          active.val += (val != 0 ? 1 : 0);
          diff = 0;
        }
      }
      if (diff != 0) {
        int w = diff / MAXBITS;
        diff -= w * MAXBITS;
        if (diff != 0) {
          if (w > 1) {
            appendCounter(0, w);
          } else if (w != 0) {
            appendLiteral();
          }
          active.nbits = diff;
          active.val += (val != 0 ? 1 : 0);
        } else if (val != 0) {
          if (w > 2) {
            appendCounter(0, w - 1);
          } else if (w == 2) {
            appendLiteral();
          }
          active.val = 1;
          appendLiteral();
        } else {
          if (w > 1) {
            appendCounter(0, w);
          } else if (w != 0) {
            appendLiteral();
          }
        }
      }

      if (numBits() != ind + 1) logger.warning("Warning");

      if (nset != 0) nset += (val != 0 ? 1 : 0);

      return;
    } else if (ind >= nbits) { // modify an active bit
      int u = active.val;
      if (val != 0) {
        active.val |= (1 << (active.nbits - (ind - nbits) - 1));
      } else {
        active.val &= ~(1 << (active.nbits - (ind - nbits) - 1));
      }
      if (nset != 0 && (u != active.val)) nset += (val != 0 ? 1 : -1);
      return;
    } else if (vec.size() * MAXBITS == nbits) { // uncompressed
      int i = ind / MAXBITS;
      int u = vec.get(i);
      int w = (1 << (SECONDBIT - (ind % MAXBITS)));

      if (val != 0) vec.setQuick(i, u |= w);
      else vec.setQuick(i, u &= ~w);
      if (nset != 0 && (vec.getQuick(i) != u)) nset += (val != 0 ? 1 : -1);
      return;
    }

    // the code after this has not been verified at all...
    // should proceed with caution.
    // compressed bit vector --
    // the bit to be modified is in vec
    if (RUN_UNTESTED_CODE) {
      int idx = 0;
      int compressed = 0, cnt = 0, ind1 = 0, ind0 = ind;
      int current = 0; // current bit value
      while ((ind0 > 0) && (idx < vec.size())) {
        int v = vec.getQuick(idx);

        if (isAFill(v)) { // a fill
          cnt = ((v) & MAXCNT) * MAXBITS;
          if (cnt > ind0) { // found the location
            current = (isOneFill(v) ? 1 : 0);
            compressed = 1;
            ind1 = ind0;
            ind0 = 0;
          } else {
            ind0 -= cnt;
            ind1 = ind0;
            ++idx;
          }
        } else { // a literal word
          cnt = MAXBITS;
          if (MAXBITS > ind0) { // found the location
            current = (1 & ((v) >>> (SECONDBIT - ind0)));
            compressed = 0;
            ind1 = ind0;
            ind0 = 0;
          } else {
            ind0 -= MAXBITS;
            ind1 = ind0;
            ++idx;
          }
        }
      } // while (ind...

      if (ind1 == 0) { // set current and compressed
        int v = vec.getQuick(idx);
        if (isAFill(v)) {
          cnt = (v & MAXCNT) * MAXBITS;
          current = (isOneFill(v) ? 1 : 0);
          compressed = 1;
        } else {
          cnt = MAXBITS;
          current = (v >>> SECONDBIT);
          compressed = 0;
        }
      }

      if (ind0 > 0) // has not found the right location yet.
      {
        if (ind0 < active.nbits) { // in the active word
          ind1 = (1 << (active.nbits - ind0 - 1));
          if (val != 0) {
            active.val |= ind1;
          } else {
            active.val &= ~ind1;
          }
        } else { // extends the current bit vector
          ind1 = ind0 - active.nbits - 1;
          appendWord(HEADER0 | (ind1 / MAXBITS));
          for (ind1 %= MAXBITS; ind1 > 0; --ind1) addOneBit(0);
          addOneBit(val != 0 ? 1 : 0);
        }
        if (nset != 0) nset += val != 0 ? 1 : -1;
        return;
      }

      // locate the bit to be changed, lots of work hidden here
      if (current == val) return; // nothing to do

      int v = vec.getQuick(idx);
      // need to actually modify the bit
      if (compressed == 0) {
        // toggle a single bit of a literal word
        v ^= (1 << (SECONDBIT - ind1));
        vec.setQuick(idx, v);
      } else if (ind1 < MAXBITS) {
        // bit to be modified is in the first word, two pieces
        --v;
        vec.set(idx, v);
        if ((v & MAXCNT) == 1) {
          v = (current != 0) ? ALLONES : 0;
          vec.setQuick(idx, v);
        }
        int w = 1 << (SECONDBIT - ind1);
        if (val == 0) w ^= ALLONES;

        vec.beforeInsert(idx, w);
        idx++;
      } else if (cnt - ind1 <= MAXBITS) {
        // bit to be modified is in the last word, two pieces
        --(v);
        vec.setQuick(idx, v);
        if ((v & MAXCNT) == 1) {
          v = (current != 0) ? ALLONES : 0;
          vec.setQuick(idx, v);
        }
        int w = 1 << (cnt - ind1 - 1);
        if (val == 0) w ^= ALLONES;
        ++idx;
        vec.beforeInsert(idx, w);
      } else { // the counter breaks into three pieces
        int u[] = new int[2], w;
        u[0] = ind1 / MAXBITS;
        w = (v & MAXCNT) - u[0] - 1;
        u[1] = 1 << (SECONDBIT - ind1 + u[0] * MAXBITS);
        if (val == 0) {
          u[0] = (u[0] > 1) ? (HEADER1 | u[0]) : (ALLONES);
          u[1] ^= ALLONES;
          w = (w > 1) ? (HEADER1 | w) : (ALLONES);
        } else {
          u[0] = (u[0] > 1) ? (HEADER0 | u[0]) : 0;
          w = (w > 1) ? (HEADER0 | w) : 0;
        }
        vec.setQuick(idx, w);
        vec.beforeInsertAllOf(idx, Arrays.asList(u));
      }

      if (nset != 0) nset += val != 0 ? 1 : -1;
    } else {
      throw new AssertionError("Untested code detected, would rather die than run this");
    }
  }
예제 #5
0
  /**
   * Returns a new WAH compressed bitset after anding the current bitset with the <i>other</i>
   * bitset.
   *
   * @param other the bitset to and with
   * @return The resulting bitset
   */
  public WAHBitSet and(WAHBitSet other) {
    WAHBitSet ret = new WAHBitSet();

    // ensure that they have the same bit length.
    if (this.numBits() < other.numBits()) {
      this.setBit(other.numBits() - 1, 0);
    } else if (this.numBits() > other.numBits()) {
      other.setBit(numBits() - 1, 0);
    }

    // if there is something in the vector.
    if (vec.size() > 0) {
      // create new run objects and decode them.
      run xrun = new run(vec), yrun = new run(other.vec);
      xrun.decode();
      yrun.decode();
      do {
        // if you finished a run, then get the next one.
        if (xrun.nWords == 0) {
          xrun.inc();
          xrun.decode();
        }

        if (yrun.nWords == 0) {
          yrun.inc();
          yrun.decode();
        }

        if (xrun.isFill()) {
          if (yrun.isFill()) {
            // both are fills... this is the best.
            int nWords = Math.min(xrun.nWords, yrun.nWords);
            ret.appendFill(nWords, xrun.fillWord & yrun.fillWord);
            xrun.nWords -= nWords;
            yrun.nWords -= nWords;
          } else {
            // just cut through the other run
            chewUpRun(xrun, ret, yrun);
          }
        } else if (yrun.isFill()) {
          // again do the same, with different order.
          chewUpRun(yrun, ret, xrun);
        } else {
          // both are literals, so get the new literal and
          // append it to the return value.
          ret.active.val = xrun.get() & yrun.get();
          ret.appendLiteral();
          yrun.nWords = 0;
          xrun.nWords = 0;
        }
        // till they are not at the end.
      } while (!(xrun.end() && yrun.end()));
    }

    // set the active word.
    ret.active.val = this.active.val & other.active.val;
    ret.active.nbits = this.active.nbits;

    // ensure that the counts are set properly.
    ret.doCount();

    return ret;
  }