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) {