/** * Compute the xor aggregate using a temporary uncompressed bitmap. * * @param container where the aggregate is written * @param bufSize buffer size used during the computation in 64-bit words * @param bitmaps the source bitmaps */ public static void bufferedxorWithContainer( final BitmapStorage32 container, final int bufSize, final EWAHCompressedBitmap32... bitmaps) { int range = 0; EWAHCompressedBitmap32[] sbitmaps = bitmaps.clone(); Arrays.sort( sbitmaps, new Comparator<EWAHCompressedBitmap32>() { @Override public int compare(EWAHCompressedBitmap32 a, EWAHCompressedBitmap32 b) { return b.sizeInBits() - a.sizeInBits(); } }); java.util.ArrayList<IteratingBufferedRunningLengthWord32> al = new java.util.ArrayList<IteratingBufferedRunningLengthWord32>(); for (EWAHCompressedBitmap32 bitmap : sbitmaps) { if (bitmap.sizeInBits() > range) range = bitmap.sizeInBits(); al.add(new IteratingBufferedRunningLengthWord32(bitmap)); } int[] hardbitmap = new int[bufSize]; int maxr = al.size(); while (maxr > 0) { int effective = 0; for (int k = 0; k < maxr; ++k) { if (al.get(k).size() > 0) { int eff = IteratorAggregation32.inplacexor(hardbitmap, al.get(k)); if (eff > effective) effective = eff; } else maxr = k; } for (int k = 0; k < effective; ++k) container.addWord(hardbitmap[k]); Arrays.fill(hardbitmap, 0); } container.setSizeInBitsWithinLastWord(range); }
/** * Simple algorithm that computes the XOR aggregate. * * @param bitmaps input bitmaps * @return new bitmap containing the aggregate */ public static EWAHCompressedBitmap32 xor(final Iterator<EWAHCompressedBitmap32> bitmaps) { PriorityQueue<EWAHCompressedBitmap32> pq = new PriorityQueue<EWAHCompressedBitmap32>( 32, new Comparator<EWAHCompressedBitmap32>() { @Override public int compare(EWAHCompressedBitmap32 a, EWAHCompressedBitmap32 b) { return a.sizeInBytes() - b.sizeInBytes(); } }); while (bitmaps.hasNext()) pq.add(bitmaps.next()); if (pq.isEmpty()) return new EWAHCompressedBitmap32(); while (pq.size() > 1) { EWAHCompressedBitmap32 x1 = pq.poll(); EWAHCompressedBitmap32 x2 = pq.poll(); pq.add(x1.xor(x2)); } return pq.poll(); }
/** * Simple algorithm that computes the XOR aggregate. * * @param bitmaps input bitmaps * @return new bitmap containing the aggregate */ public static EWAHCompressedBitmap32 xor(final EWAHCompressedBitmap32... bitmaps) { PriorityQueue<EWAHCompressedBitmap32> pq = new PriorityQueue<EWAHCompressedBitmap32>( bitmaps.length, new Comparator<EWAHCompressedBitmap32>() { @Override public int compare(EWAHCompressedBitmap32 a, EWAHCompressedBitmap32 b) { return a.sizeInBytes() - b.sizeInBytes(); } }); Collections.addAll(pq, bitmaps); if (pq.isEmpty()) return new EWAHCompressedBitmap32(); while (pq.size() > 1) { EWAHCompressedBitmap32 x1 = pq.poll(); EWAHCompressedBitmap32 x2 = pq.poll(); pq.add(x1.xor(x2)); } return pq.poll(); }
/** * Uses a priority queue to compute the xor aggregate. * * <p>The content of the container is overwritten. * * <p>This algorithm runs in linearithmic time (O(n log n)) with respect to the number of bitmaps. * * @param container where we write the result * @param bitmaps to be aggregated */ public static void xorToContainer( final BitmapStorage32 container, final EWAHCompressedBitmap32... bitmaps) { if (bitmaps.length < 2) throw new IllegalArgumentException("We need at least two bitmaps"); PriorityQueue<EWAHCompressedBitmap32> pq = new PriorityQueue<EWAHCompressedBitmap32>( bitmaps.length, new Comparator<EWAHCompressedBitmap32>() { @Override public int compare(EWAHCompressedBitmap32 a, EWAHCompressedBitmap32 b) { return a.sizeInBytes() - b.sizeInBytes(); } }); Collections.addAll(pq, bitmaps); while (pq.size() > 2) { EWAHCompressedBitmap32 x1 = pq.poll(); EWAHCompressedBitmap32 x2 = pq.poll(); pq.add(x1.xor(x2)); } pq.poll().xorToContainer(pq.poll(), container); }
@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(); }