Author: j16sdiz
Date: 2008-06-20 13:34:19 +0000 (Fri, 20 Jun 2008)
New Revision: 20521

Modified:
   
branches/saltedhashstore/freenet/src/freenet/store/SaltedHashFreenetStore.java
   branches/saltedhashstore/freenet/src/freenet/support/BloomFilter.java
Log:
rebuild bloom filter


Modified: 
branches/saltedhashstore/freenet/src/freenet/store/SaltedHashFreenetStore.java
===================================================================
--- 
branches/saltedhashstore/freenet/src/freenet/store/SaltedHashFreenetStore.java  
    2008-06-20 13:33:53 UTC (rev 20520)
+++ 
branches/saltedhashstore/freenet/src/freenet/store/SaltedHashFreenetStore.java  
    2008-06-20 13:34:19 UTC (rev 20521)
@@ -11,6 +11,7 @@
 import java.nio.channels.FileChannel;
 import java.security.MessageDigest;
 import java.text.DecimalFormat;
+import java.util.AbstractList;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.LinkedList;
@@ -839,16 +840,21 @@
                        while (!shutdown) {
                                synchronized (cleanerLock) {
                                        long _prevStoreSize;
+                                       boolean _rebuildBloom;

                                        configLock.readLock().lock();
                                        try {
                                                _prevStoreSize = prevStoreSize;
+                                               _rebuildBloom = rebuildBloom;
                                        } finally {
                                                configLock.readLock().unlock();
                                        }

                                        if (_prevStoreSize != 0)
                                                resizeStore(_prevStoreSize);
+                                       
+                                       if (_rebuildBloom)
+                                               rebuildBloom();

                                        cleanerLock.notifyAll();
                                        try {
@@ -927,6 +933,54 @@
                }

                /**
+                * Rebuild bloom filter
+                */
+               private void rebuildBloom() {
+                       if (bloomFilter == null)
+                               return;
+                       
+                       Logger.normal(this, "Start rebuilding bloom filter for 
" + callback);
+                       
+                       bloomFilter.fork();
+                       List<Entry> buildList = new AbstractList<Entry>() {
+                               @Override
+                               public void add(int index, Entry entry) {
+                                       
bloomFilter.updateFilter(entry.getDigestedRoutingKey());
+                               }
+
+                               @Override
+                               public Entry get(int index) {
+                                       return null;
+                               }
+
+                               @Override
+                               public int size() {
+                                       return 0;
+                               }
+
+                       };
+
+                       for (long curOffset = 0; curOffset < storeSize; 
curOffset += RESIZE_MEMORY_ENTRIES) {
+                               if (shutdown) {
+                                       bloomFilter.discard();
+                                       return;
+                               }
+                               batchReadEntries(curOffset, 
RESIZE_MEMORY_ENTRIES, buildList, false);
+                               Logger.normal(this, "Rebuilding bloom filter 
for " + callback + ": " + curOffset + "/" + storeSize);
+                       }
+
+                       bloomFilter.merge();
+                       Logger.normal(this, "Finish rebuilding bloom filter for 
" + callback);
+
+                       configLock.writeLock().lock();
+                       try {
+                               rebuildBloom = false;
+                       } finally {
+                               configLock.writeLock().unlock();
+                       }
+               }
+
+               /**
                 * Read a list of items from store. In resizing mode, only old 
items are read and the
                 * original offsets are freed.
                 * 

Modified: branches/saltedhashstore/freenet/src/freenet/support/BloomFilter.java
===================================================================
--- branches/saltedhashstore/freenet/src/freenet/support/BloomFilter.java       
2008-06-20 13:33:53 UTC (rev 20520)
+++ branches/saltedhashstore/freenet/src/freenet/support/BloomFilter.java       
2008-06-20 13:34:19 UTC (rev 20521)
@@ -116,6 +116,10 @@
                byte b = filter.get(offset / 8);
                b |= 1 << (offset % 8);
                filter.put(offset / 8, b);
+               
+               if (forkedFilter != null) {
+                       forkedFilter.setBit(offset);
+               }
        }

        public void force() {
@@ -123,7 +127,49 @@
                        ((MappedByteBuffer) filter).force();
                }
        }
+       
+       protected BloomFilter forkedFilter;

+       /**
+        * Create an empty, in-memory copy of bloom filter. New updates are 
written to both filters.
+        * This is written back to disk on #merge()
+        */
+       public void fork() {
+               lock.writeLock().lock();
+               try {
+                       forkedFilter = new BloomFilter(length, k);
+               } finally {
+                       lock.writeLock().unlock();
+               }
+       }
+
+       public void discard() {
+               lock.writeLock().lock();
+               try {
+                       forkedFilter = null;
+               } finally {
+                       lock.writeLock().unlock();
+               }
+       }
+       
+       public void merge() {
+               lock.writeLock().lock();
+               try {
+                       if (forkedFilter == null)
+                               return;
+
+                       filter.position(0);
+                       forkedFilter.filter.position(0);
+
+                       filter.put(forkedFilter.filter);
+
+                       filter.position(0);
+                       forkedFilter = null;
+               } finally {
+                       lock.writeLock().unlock();
+               }
+       }
+
        @Override
        protected void finalize() {
                if (filter != null) {


Reply via email to