/* This code is part of Freenet. It is distributed under the GNU General * Public License, version 2 (or at your option any later version). See * http://www.gnu.org/ for further details of the GPL. */ package freenet.support; import freenet.support.io.Closer; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.channels.FileChannel.MapMode; /** * @author sdiz */ public class BinaryBloomFilter extends BloomFilter { /** * Constructor * * @param length * length in bits */ protected BinaryBloomFilter(int length, int k) { super(length, k); filter = ByteBuffer.allocate(this.length / 8); } /** * Constructor * * @param file * disk file * @param length * length in bits * @throws IOException */ protected BinaryBloomFilter(File file, int length, int k) throws IOException { super(length, k); if (!file.exists() || file.length() != length / 8) needRebuild = true; RandomAccessFile raf = new RandomAccessFile(file, "rw"); FileChannel channel = null; try { raf.setLength(length / 8); channel = raf.getChannel(); filter = channel.map(MapMode.READ_WRITE, 0, length / 8).load(); } finally { Closer.close(raf); Closer.close(channel); } } public BinaryBloomFilter(ByteBuffer slice, int length, int k) { super(length, k); filter = slice; } @Override public void removeKey(byte[] key) { // ignore } @Override protected boolean getBit(int offset) { return (filter.get(offset / 8) & (1 << (offset % 8))) != 0; } @Override protected void setBit(int offset) { byte b = filter.get(offset / 8); b |= 1 << (offset % 8); filter.put(offset / 8, b); } @Override protected void unsetBit(int offset) { // NO-OP } @Override public void fork(int k) { lock.writeLock().lock(); try { File tempFile = File.createTempFile("bloom-", ".tmp"); tempFile.deleteOnExit(); forkedFilter = new BinaryBloomFilter(tempFile, length, k); } catch (IOException e) { forkedFilter = new BinaryBloomFilter(length, k); } finally { lock.writeLock().unlock(); } } }