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; }
/** * This is an optimization over the and function. This does not create new bitset. This just * counts the number of 1 bits common between the two bitsets. * * @param other the bitset to and with. * @return the number of 1s common between two bitsets. */ public int andSize(WAHBitSet other) { int size = 0; // 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); if ((xrun.fillWord & yrun.fillWord) == 1) { size += nWords * MAXBITS; } xrun.nWords -= nWords; yrun.nWords -= nWords; } else { size += countInRun(xrun, yrun); } } else if (yrun.isFill()) { size += countInRun(yrun, xrun); } else { int val = xrun.get() & yrun.get(); if (val > 0) size += Integer.bitCount(val); yrun.nWords = 0; xrun.nWords = 0; } } while (!(xrun.end() && yrun.end())); } size += Integer.bitCount(this.active.val & other.active.val); return size; }
public void decode() { int v = vec.get(idx); if (WAHBitSet.isAFill(v)) { fillWord = (isOneFill(v) ? ALLONES : 0); nWords = v & MAXCNT; fill = true; } else { nWords = 1; fill = false; } }
private static void chewUpRun(run xrun, WAHBitSet ret, run yrun) { if (xrun.fillWord == 0) { // trye to advance, and see how much you can advance. int inc = yrun.inc(xrun.nWords); ret.appendFill(inc, 0); xrun.nWords -= inc; } else { while (true) { int v = yrun.get(); if (isAFill(v)) { yrun.decode(); return; } ret.appendCompressed(v); xrun.nWords--; if (xrun.nWords == 0) break; yrun.inc(); } } yrun.nWords = 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; }