Author: toad
Date: 2007-08-11 12:53:51 +0000 (Sat, 11 Aug 2007)
New Revision: 14597

Modified:
   trunk/freenet/src/freenet/client/ArchiveManager.java
   trunk/freenet/src/freenet/client/ArchiveStoreContext.java
   trunk/freenet/src/freenet/client/RealArchiveStoreItem.java
Log:
Remove incrementSpace/decrementSpace. Call close() directly, inside the 
ArchiveManager lock:
- much more accurate space usage limiting
- won't get nasty race conditions where we have space used but nothing to 
remove, or the same due to exceptions/throwables
- ArchiveManager lock may be held during expensive deletes
- simpler code

Modified: trunk/freenet/src/freenet/client/ArchiveManager.java
===================================================================
--- trunk/freenet/src/freenet/client/ArchiveManager.java        2007-08-11 
12:43:04 UTC (rev 14596)
+++ trunk/freenet/src/freenet/client/ArchiveManager.java        2007-08-11 
12:53:51 UTC (rev 14597)
@@ -147,7 +147,14 @@
         * @param item The ArchiveStoreItem to remove.
         */
        synchronized void removeCachedItem(ArchiveStoreItem item) {
-               storedData.removeKey(item.key); 
+               long size = item.spaceUsed();
+               storedData.removeKey(item.key);
+               // Hard disk space limit = remove it here.
+               // Soft disk space limit would be to remove it outside the lock.
+               // Soft disk space limit = we go over the limit significantly 
when we
+               // are overloaded.
+               cachedData -= size;
+               item.close();
        }

        /**
@@ -400,7 +407,7 @@
         * callback != null.
         */
        private ArchiveStoreItem addStoreElement(ArchiveStoreContext ctx, 
FreenetURI key, String name, TempStoreElement temp, MutableBoolean gotElement, 
String callbackName, ArchiveExtractCallback callback) throws 
ArchiveFailureException {
-               RealArchiveStoreItem element = new RealArchiveStoreItem(this, 
ctx, key, name, temp);
+               RealArchiveStoreItem element = new RealArchiveStoreItem(ctx, 
key, name, temp);
                if(logMINOR) Logger.minor(this, "Adding store element: 
"+element+" ( "+key+ ' ' +name+" size "+element.spaceUsed()+" )");
                ArchiveStoreItem oldItem;
                // Let it throw, if it does something is drastically wrong
@@ -411,13 +418,16 @@
                synchronized (this) {
                        oldItem = (ArchiveStoreItem) 
storedData.get(element.key);
                        storedData.push(element.key, element);
+                       cachedData += element.spaceUsed();
+                       if(oldItem != null) {
+                               cachedData -= oldItem.spaceUsed();
+                               oldItem.close();
+                       }
                }
                if(matchBucket != null) {
                        callback.gotBucket(matchBucket);
                        gotElement.value = true;
                }
-               if(oldItem != null)
-                       oldItem.close();
                return element;
        }

@@ -426,21 +436,25 @@
         * Call synchronized on storedData.
         */
        private void trimStoredData() {
+               synchronized(this) {
                while(true) {
                        ArchiveStoreItem item;
-                       synchronized(this) {
                                if(cachedData <= maxCachedData && 
storedData.size() <= maxCachedElements) return;
                                if(storedData.isEmpty()) {
                                        // Race condition? cachedData out of 
sync?
                                        Logger.error(this, "storedData is empty 
but still over limit: cachedData="+cachedData+" / "+maxCachedData);
                                        return;
                                }
-                               item = (ArchiveStoreItem) 
storedData.popValue();        
-                       }
+                               item = (ArchiveStoreItem) storedData.popValue();
+                               long space = item.spaceUsed();
+                               cachedData -= space;
+                               // Hard limits = delete file within lock, soft 
limits = delete outside of lock
+                               // Here we use a hard limit
                        if(logMINOR)
                                Logger.minor(this, "Dropping "+item+" : 
cachedData="+cachedData+" of "+maxCachedData);
                        item.close();
                }
+               }
        }

        /** 
@@ -476,12 +490,4 @@
                        return Metadata.ARCHIVE_ZIP;
                else throw new IllegalArgumentException(); 
        }
-
-       synchronized void decrementSpace(long spaceUsed) {
-               cachedData -= spaceUsed;
-       }
-
-       synchronized void incrementSpace(long spaceUsed) {
-               cachedData += spaceUsed;
-       }
 }

Modified: trunk/freenet/src/freenet/client/ArchiveStoreContext.java
===================================================================
--- trunk/freenet/src/freenet/client/ArchiveStoreContext.java   2007-08-11 
12:43:04 UTC (rev 14596)
+++ trunk/freenet/src/freenet/client/ArchiveStoreContext.java   2007-08-11 
12:53:51 UTC (rev 14597)
@@ -123,12 +123,10 @@

        /** Notify that an archive store item with this key has been expelled 
from the cache. */
        public void removeItem(ArchiveStoreItem item) {
-               long spaceUsed = item.spaceUsed();
                synchronized(myItems) {
                        if(myItems.remove(item) == null) return; // only 
removed once
                }
                item.innerClose();
-               manager.decrementSpace(spaceUsed);
        }

        public short getArchiveType() {

Modified: trunk/freenet/src/freenet/client/RealArchiveStoreItem.java
===================================================================
--- trunk/freenet/src/freenet/client/RealArchiveStoreItem.java  2007-08-11 
12:43:04 UTC (rev 14596)
+++ trunk/freenet/src/freenet/client/RealArchiveStoreItem.java  2007-08-11 
12:53:51 UTC (rev 14597)
@@ -12,7 +12,6 @@

 class RealArchiveStoreItem extends ArchiveStoreItem {

-       private final ArchiveManager manager;
        private final File myFilename;
        private final MultiReaderBucket mb;
        private final Bucket bucket;
@@ -25,15 +24,13 @@
         * @param temp The TempStoreElement currently storing the data.
         * @param manager The parent ArchiveManager within which this item is 
stored.
         */
-       RealArchiveStoreItem(ArchiveManager manager, ArchiveStoreContext ctx, 
FreenetURI key2, String realName, TempStoreElement temp) {
+       RealArchiveStoreItem(ArchiveStoreContext ctx, FreenetURI key2, String 
realName, TempStoreElement temp) {
                super(new ArchiveKey(key2, realName), ctx);
-               this.manager = manager;
                mb = new MultiReaderBucket(temp.bucket);
                this.bucket = mb.getReaderBucket();
                temp.underBucket.setReadOnly();
                this.myFilename = temp.underBucket.getFile();
                spaceUsed = FileUtil.estimateUsage(myFilename, 
temp.underBucket.size());
-               this.manager.incrementSpace(spaceUsed);
        }

        /**


Reply via email to