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();
+               }
+       }
+}


Reply via email to