Author: j16sdiz
Date: 2008-05-21 06:34:43 +0000 (Wed, 21 May 2008)
New Revision: 19998

Modified:
   
branches/saltedhashstore/freenet/src/freenet/store/SaltedHashFreenetStore.java
Log:
Optimization
 - don't unlockEntry in probeEntry0() on found
 - write first offset on collision


Modified: 
branches/saltedhashstore/freenet/src/freenet/store/SaltedHashFreenetStore.java
===================================================================
--- 
branches/saltedhashstore/freenet/src/freenet/store/SaltedHashFreenetStore.java  
    2008-05-21 06:34:22 UTC (rev 19997)
+++ 
branches/saltedhashstore/freenet/src/freenet/store/SaltedHashFreenetStore.java  
    2008-05-21 06:34:43 UTC (rev 19998)
@@ -105,6 +105,8 @@
                        return null;
                }

+               unlockEntry(entry.curOffset);
+               
                try {
                        StorableBlock block = 
entry.getStorableBlock(routingKey, fullKey);
                        incHits();
@@ -116,6 +118,14 @@
                }
        }

+       /**
+        * Find and lock an entry with a specific routing key. <strong>You have 
to unlock the entry
+        * explicitly yourself!</strong>
+        * 
+        * @param routingKey
+        * @return <code>Entry</code> object
+        * @throws IOException
+        */
        private Entry probeEntry(byte[] routingKey) throws IOException {
                Entry entry = probeEntry0(routingKey, storeSize);

@@ -126,7 +136,7 @@
        }

        private Entry probeEntry0(byte[] routingKey, long probeStoreSize) 
throws IOException {
-               Entry entry;
+               Entry entry = null;
                long[] offset = getOffsetFromPlainKey(routingKey, 
probeStoreSize);

                for (int i = 0; i < offset.length; i++) {
@@ -139,15 +149,16 @@
                        }
                        try {
                                entry = readEntry(offset[i], routingKey);
+                               if (entry != null)
+                                       return entry;
                        } catch (EOFException e) {
                                // may occur on resize, silent it a bit
                                Logger.error(this, "EOFException on 
probeEntry", e);
                                continue;
                        } finally {
-                               unlockEntry(offset[i]);
+                               if (entry == null)
+                                       unlockEntry(offset[i]);
                        }
-                       if (entry != null)
-                               return entry;
                }
                return null;
        }
@@ -159,9 +170,10 @@

                // don't use fetch(), as fetch() would do a miss++/hit++
                Entry oldEntry = probeEntry(routingKey);
-
                if (oldEntry != null) {
+                       long oldOffset = oldEntry.curOffset;
                        try {
+                       try {
                                StorableBlock oldBlock = 
oldEntry.getStorableBlock(routingKey, fullKey);
                                if (!collisionPossible)
                                        return;
@@ -174,6 +186,14 @@
                        } catch (KeyVerifyException e) {
                                // ignore
                        }
+                       
+                       // Overwrite old offset
+                       Entry entry = new Entry(routingKey, header, data);
+                       writeEntry(entry, oldOffset);
+                       return;
+                       } finally {
+                               unlockEntry(oldOffset);
+                       }
                }

                Entry entry = new Entry(routingKey, header, data);
@@ -185,7 +205,7 @@
                                return;
                        }
                        try {
-                               if (isFree(offset[i], entry)) {
+                               if (isFree(offset[i])) {
                                        if (logDEBUG)
                                                Logger.debug(this, "probing, 
write to i=" + i + ", offset=" + offset[i]);
                                        writeEntry(entry, offset[i]);
@@ -197,19 +217,18 @@
                        }
                }

-               // no free blocks?
-               int i = random.nextInt(offset.length);
-               if (!lockEntry(offset[i])) {
-                       Logger.error(this, "can't lock entry: " + offset[i]);
+               // no free blocks, overwrite the first one
+                       if (!lockEntry(offset[0])) {
+                               Logger.error(this, "can't lock entry: " + 
offset[0]);
                        return;
                }
                try {
                        if (logDEBUG)
-                               Logger.debug(this, "collision, write to i=" + i 
+ ", offset=" + offset[i]);
-                       writeEntry(entry, offset[i]);
+                               Logger.debug(this, "collision, write to i=0, 
offset=" + offset[0]);
+                               writeEntry(entry, offset[0]);
                        incWrites();
                } finally {
-                       unlockEntry(offset[i]);
+                       unlockEntry(offset[0]);
                }
        }

@@ -272,7 +291,7 @@
                private byte[] data;

                private boolean isEncrypted;
-               public long curOffset;
+               public long curOffset = -1;

                /**
                 * Create a new entry
@@ -573,6 +592,8 @@
                        if (status == -1)
                                throw new EOFException();
                } while (bf.hasRemaining());
+               
+               entry.curOffset = offset;
        }

        /**
@@ -594,18 +615,16 @@
        }

        /**
-        * Check if a block is free or occupied by a specific routing key
+        * Check if a block is free
         * 
         * @param offset
-        * @param entry
-        *              entry, maybe <code>null</code>
         * @throws IOException
         */
-       private boolean isFree(long offset, Entry entry) throws IOException {
+       private boolean isFree(long offset) throws IOException {
                int split = (int) (offset % FILE_SPLIT);
-               long rawOffset = (offset / FILE_SPLIT) * entryTotalLength;
+               long rawOffset = (offset / FILE_SPLIT) * entryTotalLength + 
0x30;

-               ByteBuffer bf = ByteBuffer.allocate((int) 0x38);
+               ByteBuffer bf = ByteBuffer.allocate((int) 0x8);

                do {
                        int status = storeFC[split].read(bf, rawOffset + 
bf.position());
@@ -613,17 +632,7 @@
                                throw new EOFException();
                } while (bf.hasRemaining());

-               if ((bf.getLong(0x30) & ENTRY_FLAG_OCCUPIED) == 0) {
-                       // free
-                       return true;
-               } else if (entry != null) {
-                       // check digested key
-                       byte[] digestedRoutingKey = new byte[0x20];
-                       bf.position(0);
-                       bf.get(digestedRoutingKey);
-                       return Arrays.equals(digestedRoutingKey, 
entry.getDigestedRoutingKey());
-               }
-               return false;
+               return ((bf.getLong(0) & ENTRY_FLAG_OCCUPIED) == 0);
        }

        private void flushAndClose() {
@@ -1006,7 +1015,7 @@
                                        if (!lockEntry(newOffset[i])) // lock
                                                continue;
                                        try {
-                                               if (isFree(newOffset[i], 
entry)) {
+                                               if (isFree(newOffset[i])) {
                                                        if (logDEBUG)
                                                                Logger
                                                                        
.debug(this, "Put back old item: "
@@ -1070,7 +1079,7 @@
                        long occupied = 0;
                        while (sampled < numSample) {
                                try {
-                                       if (!isFree(samplePos, null)) {
+                                       if (!isFree(samplePos)) {
                                                occupied++;
                                        }
                                        sampled++;


Reply via email to