/** * Compute the and aggregate using a temporary uncompressed bitmap. * * <p>This function does not seek to match the "sizeinbits" attributes of the input bitmaps. * * @param container where the aggregate is written * @param bufSize buffer size used during the computation in 64-bit words (per input bitmap) * @param bitmaps the source bitmaps */ public static void bufferedandWithContainer( final BitmapStorage32 container, final int bufSize, final EWAHCompressedBitmap32... bitmaps) { java.util.LinkedList<IteratingBufferedRunningLengthWord32> al = new java.util.LinkedList<IteratingBufferedRunningLengthWord32>(); for (EWAHCompressedBitmap32 bitmap : bitmaps) { al.add(new IteratingBufferedRunningLengthWord32(bitmap)); } int[] hardbitmap = new int[bufSize * bitmaps.length]; for (IteratingRLW32 i : al) if (i.size() == 0) { al.clear(); break; } while (!al.isEmpty()) { Arrays.fill(hardbitmap, ~0); int effective = Integer.MAX_VALUE; for (IteratingRLW32 i : al) { int eff = IteratorAggregation32.inplaceand(hardbitmap, i); if (eff < effective) effective = eff; } for (int k = 0; k < effective; ++k) container.addWord(hardbitmap[k]); for (IteratingRLW32 i : al) if (i.size() == 0) { al.clear(); break; } } }
@Override public EWAHIterator32 next() { this.buffer.clear(); int effective = 0; Iterator<IteratingRLW32> i = this.ll.iterator(); while (i.hasNext()) { IteratingRLW32 rlw = i.next(); if (rlw.size() > 0) { int eff = IteratorAggregation32.inplacexor(this.hardbitmap, rlw); if (eff > effective) effective = eff; } else i.remove(); } for (int k = 0; k < effective; ++k) this.buffer.addWord(this.hardbitmap[k]); Arrays.fill(this.hardbitmap, 0); return this.buffer.getEWAHIterator(); }
@Override public EWAHIterator32 next() { this.buffer.clear(); IteratorAggregation32.andToContainer( this.buffer, this.bufferSize * this.ll.size(), this.ll.get(0), this.ll.get(1)); if (this.ll.size() > 2) { Iterator<IteratingRLW32> i = this.ll.iterator(); i.next(); i.next(); EWAHCompressedBitmap32 tmpbuffer = new EWAHCompressedBitmap32(); while (i.hasNext() && this.buffer.sizeInBytes() > 0) { IteratorAggregation32.andToContainer(tmpbuffer, this.buffer.getIteratingRLW(), i.next()); this.buffer.swap(tmpbuffer); tmpbuffer.clear(); } } for (IteratingRLW32 aLl : this.ll) { if (aLl.size() == 0) { this.ll.clear(); break; } } return this.buffer.getEWAHIterator(); }
/** * Write out up to max words, returns how many were written * * @param container target for writes * @param i source of data * @param max maximal number of writes * @return how many written */ protected static int discharge(final BitmapStorage32 container, IteratingRLW32 i, int max) { int counter = 0; while (i.size() > 0 && counter < max) { int l1 = i.getRunningLength(); if (l1 > 0) { if (l1 + counter > max) l1 = max - counter; container.addStreamOfEmptyWords(i.getRunningBit(), l1); counter += l1; } int l = i.getNumberOfLiteralWords(); if (l + counter > max) l = max - counter; for (int k = 0; k < l; ++k) { container.addWord(i.getLiteralWordAt(k)); } counter += l; i.discardFirstWords(l + l1); } return counter; }
protected static int inplaceand(int[] bitmap, IteratingRLW32 i) { int pos = 0; int s; while ((s = i.size()) > 0) { if (pos + s < bitmap.length) { final int L = i.getRunningLength(); if (!i.getRunningBit()) { for (int k = pos; k < pos + L; ++k) bitmap[k] = 0; } pos += L; final int LR = i.getNumberOfLiteralWords(); for (int k = 0; k < LR; ++k) bitmap[pos++] &= i.getLiteralWordAt(k); if (!i.next()) { return pos; } } else { int howMany = bitmap.length - pos; int l = i.getRunningLength(); if (pos + l > bitmap.length) { if (!i.getRunningBit()) { for (int k = pos; k < bitmap.length; ++k) bitmap[k] = 0; } i.discardFirstWords(howMany); return bitmap.length; } if (!i.getRunningBit()) for (int k = pos; k < pos + l; ++k) bitmap[k] = 0; pos += l; for (int k = 0; pos < bitmap.length; ++k) bitmap[pos++] &= i.getLiteralWordAt(k); i.discardFirstWords(howMany); return pos; } } return pos; }
protected static int inplaceor(int[] bitmap, IteratingRLW32 i) { int pos = 0; int s; while ((s = i.size()) > 0) { if (pos + s < bitmap.length) { final int L = i.getRunningLength(); if (i.getRunningBit()) java.util.Arrays.fill(bitmap, pos, pos + L, ~0); pos += L; final int LR = i.getNumberOfLiteralWords(); for (int k = 0; k < LR; ++k) bitmap[pos++] |= i.getLiteralWordAt(k); if (!i.next()) { return pos; } } else { int howmany = bitmap.length - pos; int l = i.getRunningLength(); if (pos + l > bitmap.length) { if (i.getRunningBit()) { java.util.Arrays.fill(bitmap, pos, bitmap.length, ~0); } i.discardFirstWords(howmany); return bitmap.length; } if (i.getRunningBit()) java.util.Arrays.fill(bitmap, pos, pos + l, ~0); pos += l; for (int k = 0; pos < bitmap.length; ++k) bitmap[pos++] |= i.getLiteralWordAt(k); i.discardFirstWords(howmany); return pos; } } return pos; }
/** * Compute the first few words of the XOR aggregate between two iterators. * * @param container where to write * @param desiredrlwcount number of words to be written (max) * @param rlwi first iterator to aggregate * @param rlwj second iterator to aggregate */ public static void xorToContainer( final BitmapStorage32 container, int desiredrlwcount, final IteratingRLW32 rlwi, IteratingRLW32 rlwj) { while ((rlwi.size() > 0) && (rlwj.size() > 0) && (desiredrlwcount-- > 0)) { while ((rlwi.getRunningLength() > 0) || (rlwj.getRunningLength() > 0)) { final boolean i_is_prey = rlwi.getRunningLength() < rlwj.getRunningLength(); final IteratingRLW32 prey = i_is_prey ? rlwi : rlwj; final IteratingRLW32 predator = i_is_prey ? rlwj : rlwi; if (!predator.getRunningBit()) { int index = discharge(container, prey, predator.getRunningLength()); container.addStreamOfEmptyWords(false, predator.getRunningLength() - index); predator.discardFirstWords(predator.getRunningLength()); } else { int index = dischargeNegated(container, prey, predator.getRunningLength()); container.addStreamOfEmptyWords(true, predator.getRunningLength() - index); predator.discardFirstWords(predator.getRunningLength()); } } final int nbre_literal = Math.min(rlwi.getNumberOfLiteralWords(), rlwj.getNumberOfLiteralWords()); if (nbre_literal > 0) { desiredrlwcount -= nbre_literal; for (int k = 0; k < nbre_literal; ++k) container.addWord(rlwi.getLiteralWordAt(k) ^ rlwj.getLiteralWordAt(k)); rlwi.discardFirstWords(nbre_literal); rlwj.discardFirstWords(nbre_literal); } } }
/** * Write out the content of the iterator, but as if it were all zeros. * * @param container where we write * @param i the iterator */ protected static void dischargeAsEmpty(final BitmapStorage32 container, final IteratingRLW32 i) { while (i.size() > 0) { container.addStreamOfEmptyWords(false, i.size()); i.next(); } }