Author: toad
Date: 2009-01-27 17:04:45 +0000 (Tue, 27 Jan 2009)
New Revision: 25319

Modified:
   
branches/db4o/freenet/src/freenet/support/io/PersistentBlobTempBucketFactory.java
   branches/db4o/freenet/src/freenet/support/io/PersistentTempBucketFactory.java
Log:
When a blob bucket is freed, change the in-db structures, but add it to 
almostFreedSlots. Just after commit, move the almost freed slots list into free 
slots list. Do not use DelayedFreeBucket's for blob buckets, since the above is 
more efficient.


Modified: 
branches/db4o/freenet/src/freenet/support/io/PersistentBlobTempBucketFactory.java
===================================================================
--- 
branches/db4o/freenet/src/freenet/support/io/PersistentBlobTempBucketFactory.java
   2009-01-27 16:50:44 UTC (rev 25318)
+++ 
branches/db4o/freenet/src/freenet/support/io/PersistentBlobTempBucketFactory.java
   2009-01-27 17:04:45 UTC (rev 25319)
@@ -10,6 +10,7 @@
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Random;
+import java.util.Set;
 import java.util.TreeMap;
 
 import com.db4o.ObjectContainer;
@@ -49,6 +50,10 @@
         * more. */
        private transient TreeMap<Long,PersistentBlobTempBucketTag> freeSlots;
        
+       /** Recently freed slots, cannot be reused until after commit.
+        * Similar to notCommittedBlobs. */
+       private transient TreeMap<Long,PersistentBlobTempBucketTag> 
almostFreeSlots;
+       
        private transient DBJobRunner jobRunner;
        
        private transient Random weakRandomSource;
@@ -78,6 +83,7 @@
                channel = raf.getChannel();
                notCommittedBlobs = new 
TreeMap<Long,PersistentBlobTempBucket>();
                freeSlots = new TreeMap<Long,PersistentBlobTempBucketTag>();
+               almostFreeSlots = new 
TreeMap<Long,PersistentBlobTempBucketTag>();
                jobRunner = jobRunner2;
                weakRandomSource = fastWeakRandom;
                this.ticker = ticker;
@@ -118,6 +124,7 @@
                                        }
                                        if(tag.factory != 
PersistentBlobTempBucketFactory.this) continue;
                                        
if(notCommittedBlobs.containsKey(tag.index)) continue;
+                                       
if(almostFreeSlots.containsKey(tag.index)) continue;
                                        if(freeSlots.containsKey(tag.index)) 
continue;
                                        if(tag.bucket != null) {
                                                Logger.error(this, "Bucket is 
occupied but not in notCommittedBlobs?!: "+tag+" : "+tag.bucket);
@@ -146,10 +153,10 @@
                        while(ptr > 0 && !query.execute().hasNext()) {
                                boolean stored = false;
                                
synchronized(PersistentBlobTempBucketFactory.this) {
-                                       stored = notCommittedBlobs.get(ptr) == 
null;
+                                       stored = notCommittedBlobs.get(ptr) == 
null && almostFreeSlots.get(ptr) == null;
                                        if(stored) {
                                                if(freeSlots.containsKey(ptr)) 
break;
-                                               
if(notCommittedBlobs.containsKey(ptr)) {
+                                               
if(notCommittedBlobs.containsKey(ptr) || almostFreeSlots.containsKey(ptr)) {
                                                        ptr--;
                                                        continue;
                                                }
@@ -185,6 +192,7 @@
                                for(long l = 0; l < ptr; l++) {
                                        if(freeSlots.containsKey(l)) continue;
                                        if(notCommittedBlobs.containsKey(l)) 
continue;
+                                       if(almostFreeSlots.containsKey(l)) 
continue;
                                        query = container.query();
                                        
query.constrain(PersistentBlobTempBucketTag.class);
                                        query.descend("index").constrain(l);
@@ -257,7 +265,7 @@
                        if(!freeSlots.isEmpty()) {
                                Long slot = freeSlots.firstKey();
                                PersistentBlobTempBucketTag tag = 
freeSlots.remove(slot);
-                               if(notCommittedBlobs.get(slot) != null) {
+                               if(notCommittedBlobs.get(slot) != null || 
almostFreeSlots.get(slot) != null) {
                                        Logger.error(this, "Slot "+slot+" 
already occupied by a not committed blob despite being in freeSlots!!");
                                        return null;
                                }
@@ -272,7 +280,7 @@
                        if(!freeSlots.isEmpty()) {
                                Long slot = freeSlots.firstKey();
                                PersistentBlobTempBucketTag tag = 
freeSlots.remove(slot);
-                               if(notCommittedBlobs.get(slot) != null) {
+                               if(notCommittedBlobs.get(slot) != null || 
almostFreeSlots.get(slot) != null) {
                                        Logger.error(this, "Slot "+slot+" 
already occupied by a not committed blob despite being in freeSlots!!");
                                        return null;
                                }
@@ -312,7 +320,7 @@
                        Logger.error(this, "Removing bucket "+bucket+" for slot 
"+bucket.index+" but not freed!", new Exception("debug"));
                        notCommittedBlobs.put(index, bucket);
                } else {
-                       freeSlots.put(index, tag);
+                       almostFreeSlots.put(index, tag);
                }
                tag.bucket = null;
                tag.isFree = true;
@@ -352,6 +360,11 @@
                                return;
                        }
                        long lastNotCommitted = notCommittedBlobs.isEmpty() ? 0 
: notCommittedBlobs.lastKey();
+                       long lastAlmostFreed = almostFreeSlots.isEmpty() ? 0 : 
almostFreeSlots.lastKey();
+                       if(lastNotCommitted < lastAlmostFreed) {
+                               if(logMINOR) Logger.minor(this, "Last almost 
freed: "+lastAlmostFreed+" replacing last not committed: "+lastNotCommitted);
+                               lastNotCommitted = lastAlmostFreed;
+                       }
                        double full = (double)lastNotCommitted / (double)blocks;
                        if(full > 0.8) {
                                if(logMINOR) Logger.minor(this, "Not shrinking, 
last not committed block is at "+full*100+"% ("+lastNotCommitted+" of 
"+blocks+")");
@@ -448,4 +461,9 @@
                }
        }
 
+       public synchronized void postCommit() {
+               freeSlots.putAll(almostFreeSlots);
+               almostFreeSlots.clear();
+       }
+
 }

Modified: 
branches/db4o/freenet/src/freenet/support/io/PersistentTempBucketFactory.java
===================================================================
--- 
branches/db4o/freenet/src/freenet/support/io/PersistentTempBucketFactory.java   
    2009-01-27 16:50:44 UTC (rev 25318)
+++ 
branches/db4o/freenet/src/freenet/support/io/PersistentTempBucketFactory.java   
    2009-01-27 17:04:45 UTC (rev 25319)
@@ -132,7 +132,8 @@
        public Bucket makeBucket(long size) throws IOException {
                Bucket rawBucket = null;
                if(size == BLOB_SIZE) {
-                       rawBucket = blobFactory.makeBucket();
+                       // No need for a DelayedFreeBucket, we handle this 
internally (and more efficiently) for blobs.
+                       return blobFactory.makeBucket();
                }
                if(rawBucket == null)
                        rawBucket = new 
PersistentTempFileBucket(fg.makeRandomFilename(), fg);
@@ -204,6 +205,7 @@
        }
 
        public void postCommit(ObjectContainer db) {
+               blobFactory.postCommit();
                LinkedList<DelayedFreeBucket> toFree = grabBucketsToFree();
                for(Iterator<DelayedFreeBucket> 
i=toFree.iterator();i.hasNext();) {
                        DelayedFreeBucket bucket = i.next();

_______________________________________________
cvs mailing list
[email protected]
http://emu.freenetproject.org/cgi-bin/mailman/listinfo/cvs

Reply via email to