Author: j16sdiz
Date: 2008-07-31 00:51:26 +0000 (Thu, 31 Jul 2008)
New Revision: 21517
Added:
branches/saltedhashstore/freenet/src/freenet/support/CountingBloomFilter.java
Modified:
branches/saltedhashstore/freenet/src/freenet/store/saltedhash/SaltedHashFreenetStore.java
Log:
Counting bloom filter
Modified:
branches/saltedhashstore/freenet/src/freenet/store/saltedhash/SaltedHashFreenetStore.java
===================================================================
---
branches/saltedhashstore/freenet/src/freenet/store/saltedhash/SaltedHashFreenetStore.java
2008-07-31 00:51:05 UTC (rev 21516)
+++
branches/saltedhashstore/freenet/src/freenet/store/saltedhash/SaltedHashFreenetStore.java
2008-07-31 00:51:26 UTC (rev 21517)
@@ -36,8 +36,8 @@
import freenet.store.KeyCollisionException;
import freenet.store.StorableBlock;
import freenet.store.StoreCallback;
-import freenet.support.BinaryBloomFilter;
import freenet.support.BloomFilter;
+import freenet.support.CountingBloomFilter;
import freenet.support.Fields;
import freenet.support.HTMLNode;
import freenet.support.HexUtil;
@@ -117,7 +117,7 @@
newStore |= openStoreFiles(baseDir, name);
File bloomFile = new File(this.baseDir, name + ".bloom");
- bloomFilter = new BinaryBloomFilter(bloomFile, bloomFilterSize,
bloomFilterK);
+ bloomFilter = new CountingBloomFilter(bloomFile,
bloomFilterSize, bloomFilterK);
if ((flags & FLAG_DIRTY) != 0)
System.err.println("Datastore(" + name + ") is dirty.");
Added:
branches/saltedhashstore/freenet/src/freenet/support/CountingBloomFilter.java
===================================================================
---
branches/saltedhashstore/freenet/src/freenet/support/CountingBloomFilter.java
(rev 0)
+++
branches/saltedhashstore/freenet/src/freenet/support/CountingBloomFilter.java
2008-07-31 00:51:26 UTC (rev 21517)
@@ -0,0 +1,92 @@
+/* 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 java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel.MapMode;
+
+/**
+ * @author sdiz
+ */
+public class CountingBloomFilter extends BloomFilter {
+ /**
+ * Constructor
+ *
+ * @param length
+ * length in bits
+ */
+ public CountingBloomFilter(int length, int k) {
+ super(length, k);
+ filter = ByteBuffer.allocate(length / 8 * 2);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param file
+ * disk file
+ * @param length
+ * length in bits
+ * @throws IOException
+ */
+ public CountingBloomFilter(File file, int length, int k) throws
IOException {
+ super(length, k);
+ int fileLength = length / 8 * 2;
+ if (!file.exists() || file.length() != fileLength)
+ needRebuild = true;
+
+ RandomAccessFile raf = new RandomAccessFile(file, "rw");
+ raf.setLength(fileLength);
+ filter = raf.getChannel().map(MapMode.READ_WRITE, 0,
fileLength).load();
+ }
+
+ @Override
+ protected boolean getBit(int offset) {
+ byte b = filter.get(offset / 8 * 2);
+ byte v = (byte) ((b >>> offset % 4 * 2) & 3);
+
+ return v != 0;
+ }
+
+ @Override
+ protected void setBit(int offset) {
+ byte b = filter.get(offset / 8 * 2);
+ byte v = (byte) ((b >>> offset % 4 * 2) & 3);
+
+ if (v == 3)
+ return; // overflow
+
+ b &= ~(3 << offset % 4 * 2); // unset bit
+ b |= (v + 1) << offset % 4 * 2; // set bit
+
+ filter.put(offset / 8, b);
+ }
+
+ @Override
+ protected void unsetBit(int offset) {
+ byte b = filter.get(offset / 8 * 2);
+ byte v = (byte) ((b >>> offset % 4 * 2) & 3);
+
+ if (v == 0 || v == 3)
+ return; // overflow / underflow
+
+ b &= ~(3 << offset % 4 * 2); // unset bit
+ b |= (v - 1) << offset % 4 * 2; // set bit
+
+ filter.put(offset / 8, b);
+ }
+
+ @Override
+ public void fork(int k) {
+ lock.writeLock().lock();
+ try {
+ forkedFilter = new CountingBloomFilter(length, k);
+ } finally {
+ lock.writeLock().unlock();
+ }
+ }
+}