@Override public void swap(final Buffer other) { if(other instanceof LongArray) { long[] tmp = this.buffer; this.buffer = ((LongArray)other).buffer; ((LongArray)other).buffer = tmp; int tmp2 = this.actualSizeInWords; this.actualSizeInWords = ((LongArray)other).actualSizeInWords; ((LongArray)other).actualSizeInWords = tmp2; } else { long[] tmp = new long[other.sizeInWords()]; for(int i = 0; i < other.sizeInWords(); ++i) { tmp[i] = other.getWord(i); } int tmp2 = other.sizeInWords(); other.clear(); other.removeLastWord(); other.push_back(this, 0, this.sizeInWords()); this.buffer = tmp; this.actualSizeInWords = tmp2; } }
/** * Deserialize. * * @param in the DataInput stream * @throws IOException Signals that an I/O exception has occurred. */ public void deserialize(DataInput in) throws IOException { this.sizeInBits = in.readInt(); int sizeInWords = in.readInt(); this.buffer.clear();//This creates a buffer with 1 word in it already! this.buffer.removeLastWord(); this.buffer.ensureCapacity(sizeInWords); for(int i = 0; i < sizeInWords; ++i) { this.buffer.push_back(in.readLong()); } this.rlw = new RunningLengthWord(this.buffer, in.readInt()); }
/** * throws a NonEmptyException exception when number is greater than 0 */ @Override public void addStreamOfLiteralWords(Buffer buffer, int start, int number) { for(int x = start; x < start + number ; ++x) if(buffer.getWord(x)!=0) throw nonEmptyException; }
final int usedBitsInLast = this.sizeInBits % WORD_IN_BITS; final int freeBitsInLast = WORD_IN_BITS - usedBitsInLast; if (this.buffer.getLastWord() == 0l) { this.rlw.setNumberOfLiteralWords(this.rlw.getNumberOfLiteralWords() - 1); this.buffer.removeLastWord(); this.sizeInBits -= usedBitsInLast; } else if (usedBitsInLast > 0) { final int maskShift = this.sizeInBits % WORD_IN_BITS; final long mask = ((~0l) >>> (WORD_IN_BITS - maskWidth)) << maskShift; this.buffer.orLastWord(mask); if (this.buffer.getLastWord() == ~0l) { this.buffer.removeLastWord(); this.rlw.setNumberOfLiteralWords(this.rlw.getNumberOfLiteralWords() - 1); insertEmptyWord(true); final int maskShift = this.sizeInBits % WORD_IN_BITS; final long mask = ((~0l) >>> (WORD_IN_BITS - maskWidth)) << maskShift; this.buffer.orLastWord(mask);
long mask = 1l << i % WORD_IN_BITS; if(value) { this.buffer.orWord(pos + wordPosition, mask); } else { this.buffer.andWord(pos + wordPosition, ~mask); if(this.buffer.getWord(pos + wordPosition) == emptyWord) { boolean canMergeInCurrentRLW = mergeLiteralWordInCurrentRunningLength(value, rb, rl, wordPosition); boolean canMergeInNextRLW = mergeLiteralWordInNextRunningLength(value, lw, pos, wordPosition); long nextRl = RunningLengthWord.getRunningLength(this.buffer, pos + 2); long nextLw = RunningLengthWord.getNumberOfLiteralWords(this.buffer, pos + 2); this.buffer.collapse(pos, 2); setRLWInfo(pos, value, rl + 1 + nextRl, nextLw); if(this.rlw.position >= pos+2) { this.buffer.collapse(pos + 1, 1); setRLWInfo(pos, value, rl+1, lw-1); if(this.rlw.position >= pos+2) { long nextRl = RunningLengthWord.getRunningLength(this.buffer, nextRLWPos); long nextLw = RunningLengthWord.getNumberOfLiteralWords(this.buffer, nextRLWPos); this.buffer.collapse(pos+wordPosition, 1); setRLWInfo(pos, rb, rl, lw-1); setRLWInfo(pos+wordPosition, value, nextRl+1, nextLw);
/** * Serialize. * * The current bitmap is not modified. * * @param out the DataOutput stream * @throws IOException Signals that an I/O exception has occurred. */ public void serialize(DataOutput out) throws IOException { out.writeInt(this.sizeInBits); final int siw = this.buffer.sizeInWords(); out.writeInt(siw); for(int i = 0; i < siw; ++i) { out.writeLong(this.buffer.getWord(i)); } out.writeInt(this.rlw.position); }
for (int j = 0; j < nlw; ++j) { int position = i.literalWords() + j; i.buffer().negateWord(position); this.buffer.removeLastWord(); } else { rlw1.setRunningLength(rlw1 i.buffer().andWord(i.literalWords() + rlw1.getNumberOfLiteralWords() - 1, (~0l) >>> (WORD_IN_BITS - usedBitsInLast)); return;
private void setInRunningLength(boolean value, int i, int nbits, int pos, long rl, boolean rb, long lw) { if(value != rb) { int wordPosition = (i - nbits) / WORD_IN_BITS + 1; int addedWords = (wordPosition==rl) ? 1 : 2; this.buffer.expand(pos+1, addedWords); long mask = 1l << i % WORD_IN_BITS; this.buffer.setWord(pos+1, value ? mask : ~mask); if(this.rlw.position >= pos+1) { this.rlw.position += addedWords; } if(addedWords==1) { setRLWInfo(pos, rb, rl-1, lw+1); } else { setRLWInfo(pos, rb, wordPosition-1, 1l); setRLWInfo(pos+2, rb, rl-wordPosition, lw); if(this.rlw.position == pos) { this.rlw.position += 2; } } } }
/** * Clear any set bits and set size in bits back to 0 */ @Override public void clear() { this.sizeInBits = 0; this.buffer.clear(); this.rlw.position = 0; }
@Override public EWAHCompressedBitmap clone() throws CloneNotSupportedException { EWAHCompressedBitmap clone = new EWAHCompressedBitmap(this.buffer.clone()); clone.sizeInBits = this.sizeInBits; clone.rlw = new RunningLengthWord(clone.buffer, this.rlw.position); return clone; }
@Override public void setSizeInBitsWithinLastWord(final int size) { // TODO: This method could be replaced with setSizeInBits if ((size + WORD_IN_BITS - 1) / WORD_IN_BITS > (this.sizeInBits + WORD_IN_BITS - 1) / WORD_IN_BITS) { setSizeInBits(size,false); return; } if ((size + WORD_IN_BITS - 1) / WORD_IN_BITS != (this.sizeInBits + WORD_IN_BITS - 1) / WORD_IN_BITS) throw new RuntimeException( "You can only reduce the size of the bitmap within the scope of the last word. To extend the bitmap, please call setSizeInBits(int,boolean)."); this.sizeInBits = size; final int usedBitsInLast = this.sizeInBits % WORD_IN_BITS; if (usedBitsInLast == 0) return; if (this.rlw.getNumberOfLiteralWords() == 0) { if (this.rlw.getRunningLength() > 0) { this.rlw.setRunningLength(this.rlw.getRunningLength() - 1); final long word = this.rlw.getRunningBit() ? (~0l) >>> (WORD_IN_BITS - usedBitsInLast) : 0l; this.insertLiteralWord(word); } return; } this.buffer.andLastWord((~0l) >>> (WORD_IN_BITS - usedBitsInLast)); }
/** * Get the nth literal word for the current running length word * * @param index zero based index * @return the literal word */ @Override public long getLiteralWordAt(int index) { return this.buffer.getWord(this.literalWordStartPosition + index); }
final int usedBitsInLast = this.sizeInBits % WORD_IN_BITS; final int freeBitsInLast = WORD_IN_BITS - usedBitsInLast; if (this.buffer.getLastWord() == 0l) { this.rlw.setNumberOfLiteralWords(this.rlw.getNumberOfLiteralWords() - 1); this.buffer.removeLastWord(); this.sizeInBits -= usedBitsInLast; } else if (usedBitsInLast > 0) { final int maskShift = this.sizeInBits % WORD_IN_BITS; final long mask = ((~0l) >>> (WORD_IN_BITS - maskWidth)) << maskShift; this.buffer.orLastWord(mask); if (this.buffer.getLastWord() == ~0l) { this.buffer.removeLastWord(); this.rlw.setNumberOfLiteralWords(this.rlw.getNumberOfLiteralWords() - 1); insertEmptyWord(true); final int maskShift = this.sizeInBits % WORD_IN_BITS; final long mask = ((~0l) >>> (WORD_IN_BITS - maskWidth)) << maskShift; this.buffer.orLastWord(mask);
long mask = 1l << i % WORD_IN_BITS; if(value) { this.buffer.orWord(pos + wordPosition, mask); } else { this.buffer.andWord(pos + wordPosition, ~mask); if(this.buffer.getWord(pos + wordPosition) == emptyWord) { boolean canMergeInCurrentRLW = mergeLiteralWordInCurrentRunningLength(value, rb, rl, wordPosition); boolean canMergeInNextRLW = mergeLiteralWordInNextRunningLength(value, lw, pos, wordPosition); long nextRl = RunningLengthWord.getRunningLength(this.buffer, pos + 2); long nextLw = RunningLengthWord.getNumberOfLiteralWords(this.buffer, pos + 2); this.buffer.collapse(pos, 2); setRLWInfo(pos, value, rl + 1 + nextRl, nextLw); if(this.rlw.position >= pos+2) { this.buffer.collapse(pos + 1, 1); setRLWInfo(pos, value, rl+1, lw-1); if(this.rlw.position >= pos+2) { long nextRl = RunningLengthWord.getRunningLength(this.buffer, nextRLWPos); long nextLw = RunningLengthWord.getNumberOfLiteralWords(this.buffer, nextRLWPos); this.buffer.collapse(pos+wordPosition, 1); setRLWInfo(pos, rb, rl, lw-1); setRLWInfo(pos+wordPosition, value, nextRl+1, nextLw);
/** * Serialize. * * The current bitmap is not modified. * * @param out the DataOutput stream * @throws IOException Signals that an I/O exception has occurred. */ public void serialize(DataOutput out) throws IOException { out.writeInt(this.sizeInBits); final int siw = this.buffer.sizeInWords(); out.writeInt(siw); for(int i = 0; i < siw; ++i) { out.writeLong(this.buffer.getWord(i)); } out.writeInt(this.rlw.position); }
for (int j = 0; j < nlw; ++j) { int position = i.literalWords() + j; i.buffer().negateWord(position); this.buffer.removeLastWord(); } else { rlw1.setRunningLength(rlw1 i.buffer().andWord(i.literalWords() + rlw1.getNumberOfLiteralWords() - 1, (~0l) >>> (WORD_IN_BITS - usedBitsInLast)); return;
private void setInRunningLength(boolean value, int i, int nbits, int pos, long rl, boolean rb, long lw) { if(value != rb) { int wordPosition = (i - nbits) / WORD_IN_BITS + 1; int addedWords = (wordPosition==rl) ? 1 : 2; this.buffer.expand(pos+1, addedWords); long mask = 1l << i % WORD_IN_BITS; this.buffer.setWord(pos+1, value ? mask : ~mask); if(this.rlw.position >= pos+1) { this.rlw.position += addedWords; } if(addedWords==1) { setRLWInfo(pos, rb, rl-1, lw+1); } else { setRLWInfo(pos, rb, wordPosition-1, 1l); setRLWInfo(pos+2, rb, rl-wordPosition, lw); if(this.rlw.position == pos) { this.rlw.position += 2; } } } }
/** * Clear any set bits and set size in bits back to 0 */ @Override public void clear() { this.sizeInBits = 0; this.buffer.clear(); this.rlw.position = 0; }
@Override public EWAHCompressedBitmap clone() throws CloneNotSupportedException { EWAHCompressedBitmap clone = new EWAHCompressedBitmap(this.buffer.clone()); clone.sizeInBits = this.sizeInBits; clone.rlw = new RunningLengthWord(clone.buffer, this.rlw.position); return clone; }