Author: toad
Date: 2009-01-29 17:23:46 +0000 (Thu, 29 Jan 2009)
New Revision: 25367

Modified:
   
branches/db4o/freenet/src/freenet/support/io/PersistentBlobTempBucketFactory.java
Log:
Fix OOM: query from the end of the file backwards when trying to find the last 
occupied block. IMMEDIATE mode copies everything, so could easily OOM here. Not 
any more.


Modified: 
branches/db4o/freenet/src/freenet/support/io/PersistentBlobTempBucketFactory.java
===================================================================
--- 
branches/db4o/freenet/src/freenet/support/io/PersistentBlobTempBucketFactory.java
   2009-01-29 17:22:04 UTC (rev 25366)
+++ 
branches/db4o/freenet/src/freenet/support/io/PersistentBlobTempBucketFactory.java
   2009-01-29 17:23:46 UTC (rev 25367)
@@ -350,20 +350,33 @@
                                queueMaybeShrink();
                                return;
                        }
-                       Query query = container.query();
-                       query.constrain(PersistentBlobTempBucketTag.class);
-                       query.descend("isFree").constrain(false);
-                       query.descend("index").orderDescending();
-                       ObjectSet<PersistentBlobTempBucketTag> tags = 
query.execute();
-                       long lastCommitted;
-                       if(tags.isEmpty()) {
+                       /*
+                        * Query for the non-free tag with the highest value.
+                        * This query can return a vast number of objects! And 
it's all kept in RAM in IMMEDIATE mode.
+                        * FIXME LAZY query mode may help, but would likely 
require changes to other code.
+                        * In the meantime, lets try from the end, going 
backwards by a manageable number of slots at a time...
+                        */
+                       long lastCommitted = -1;
+                       for(long threshold = blocks - 4096; threshold >= 0; 
threshold -= 4096) {
+                               Query query = container.query();
+                               
query.constrain(PersistentBlobTempBucketTag.class);
+                               query.descend("isFree").constrain(false);
+                               query.descend("index").orderDescending();
+                               
query.descend("index").constrain(threshold).greater();
+                               ObjectSet<PersistentBlobTempBucketTag> tags = 
query.execute();
+                               if(tags.isEmpty()) {
+                                       // No used slots after threshold.
+                                       continue;
+                               } else {
+                                       lastCommitted = tags.next().index;
+                                       Logger.normal(this, "No used slots in 
persistent temp file (but last not committed = "+lastNotCommitted+")");
+                                       break;
+                               }
+                       }
+                       if(lastCommitted == -1) {
                                // No used slots at all?!
                                // There may be some not committed though
-                               Logger.normal(this, "No used slots in 
persistent temp file (but last not committed = "+lastNotCommitted+")");
                                lastCommitted = 0;
-                       } else {
-                               lastCommitted = tags.next().index;
-                               if(logMINOR) Logger.minor(this, "Last committed 
slot is "+lastCommitted+" last not committed is "+lastNotCommitted);
                        }
                        full = (double) lastCommitted / (double) blocks;
                        if(full > 0.8) {

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

Reply via email to