Author: robert
Date: 2007-12-12 21:00:27 +0000 (Wed, 12 Dec 2007)
New Revision: 16508

Modified:
   trunk/freenet/src/freenet/clients/http/StatisticsToadlet.java
   trunk/freenet/src/freenet/node/Node.java
   trunk/freenet/src/freenet/node/NodeStats.java
Log:
Rough implementation of cache & store location statistics (uses a lot of memory)


Modified: trunk/freenet/src/freenet/clients/http/StatisticsToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/StatisticsToadlet.java       
2007-12-12 18:16:09 UTC (rev 16507)
+++ trunk/freenet/src/freenet/clients/http/StatisticsToadlet.java       
2007-12-12 21:00:27 UTC (rev 16508)
@@ -29,6 +29,7 @@
 import freenet.support.SizeUtil;
 import freenet.support.TimeUtil;
 import freenet.support.api.HTTPRequest;
+import freenet.support.math.SimpleRunningAverage;

 public class StatisticsToadlet extends Toadlet {

@@ -422,8 +423,52 @@
                                        "\u00a0(" + ((storeHits*100) / 
(storeAccesses)) + "%)");

                storeSizeList.addChild("li", 
-                               "Avg. access rate:\u00a0" + 
thousendPoint.format(overallAccesses/nodeUptimeSeconds) + "/sec");
+                               "Avg. access rate:\u00a0" + 
thousendPoint.format(cacheAccesses/nodeUptimeSeconds) + "/sec, 
"+thousendPoint.format(storeAccesses/nodeUptimeSeconds)+"/sec");

+               // location-based stats
+               boolean hasLoc=true;
+               double nodeLoc=0.0;
+               try {
+                       nodeLoc=node.getLocationManager().getLocation();
+               } catch (Error e) {
+                       //FIXME: PLEASE, how do we get the node location on the 
stats page?
+                       //Logger.error(this, "why?", e);
+                       e.printStackTrace();
+                       hasLoc=false;
+               }
+               double 
avgCacheLocation=node.nodeStats.avgCacheLocation.currentValue();
+               double 
avgStoreLocation=node.nodeStats.avgStoreLocation.currentValue();
+               long cacheWrites=node.nodeStats.avgCacheLocation.countReports();
+               long storeWrites=node.nodeStats.avgStoreLocation.countReports();
+               double 
avgCacheSuccess=node.nodeStats.avgCacheSuccess.currentValue();
+               double 
avgStoreSuccess=node.nodeStats.avgStoreSuccess.currentValue();
+               double furthestCacheSuccess=node.nodeStats.furthestCacheSuccess;
+               double furthestStoreSuccess=node.nodeStats.furthestStoreSuccess;
+               double storeDist=Location.distance(nodeLoc, avgStoreLocation);
+               double cacheDist=Location.distance(nodeLoc, avgCacheLocation);
+               
+               storeSizeList.addChild("li", "avgCacheLocation:\u00a0" + 
thousendPoint.format(avgCacheLocation));
+               storeSizeList.addChild("li", "avgStoreLocation:\u00a0" + 
thousendPoint.format(avgStoreLocation));
+               
+               storeSizeList.addChild("li", "avgCacheSuccess:\u00a0" + 
thousendPoint.format(avgCacheSuccess));
+               storeSizeList.addChild("li", "avgStoreSuccess:\u00a0" + 
thousendPoint.format(avgStoreSuccess));
+               
+               storeSizeList.addChild("li", "furthestCacheSuccess:\u00a0" + 
thousendPoint.format(furthestCacheSuccess));
+               storeSizeList.addChild("li", "furthestStoreSuccess:\u00a0" + 
thousendPoint.format(furthestStoreSuccess));
+               
+               storeSizeList.addChild("li", "cacheWrites:\u00a0" + 
cacheWrites);
+               storeSizeList.addChild("li", "storeWrites:\u00a0" + 
storeWrites);
+               
+               if (hasLoc) {
+                       storeSizeList.addChild("li", "cacheDist:\u00a0" + 
thousendPoint.format(cacheDist));
+                       storeSizeList.addChild("li", "storeDist:\u00a0" + 
thousendPoint.format(storeDist));
+                       long 
cacheLocationReports=((SimpleRunningAverage)node.nodeStats.avgCacheLocation).countReports();
+                       long 
storeLocationReports=((SimpleRunningAverage)node.nodeStats.avgStoreLocation).countReports();
+                       double 
cachePrimePercent=((1.0*cacheLocationReports)/cachedKeys);
+                       double 
storePrimePercent=((1.0*storeLocationReports)/storeKeys);
+                       storeSizeList.addChild("li", 
"locStatsReliability:\u00a0"+fix3p1pct.format(cachePrimePercent)+" / 
"+fix3p1pct.format(storePrimePercent));
+               }
+               
        }

        private void drawUnclaimedFIFOMessageCountsBox(HTMLNode 
unclaimedFIFOMessageCountsInfobox) {

Modified: trunk/freenet/src/freenet/node/Node.java
===================================================================
--- trunk/freenet/src/freenet/node/Node.java    2007-12-12 18:16:09 UTC (rev 
16507)
+++ trunk/freenet/src/freenet/node/Node.java    2007-12-12 21:00:27 UTC (rev 
16508)
@@ -247,8 +247,8 @@

        /** The maximum number of keys stored in each of the datastores, cache 
and store combined. */
        private long maxTotalKeys;
-       private long maxCacheKeys;
-       private long maxStoreKeys;
+       long maxCacheKeys;
+       long maxStoreKeys;
        /** The maximum size of the datastore. Kept to avoid rounding turning 
5G into 5368698672 */
        private long maxTotalDatastoreSize;
        /** If true, store shrinks occur immediately even if they are over 10% 
of the store size. If false,
@@ -1767,11 +1767,23 @@
        public SSKBlock fetch(NodeSSK key, boolean dontPromote) {
                if(logMINOR) dumpStoreHits();
                try {
+                       double loc=key.toNormalizedDouble();
+                       double dist=Location.distance(lm.getLocation(), loc);
+                       nodeStats.avgRequestLocation.report(loc);
                        SSKBlock block = sskDatastore.fetch(key, dontPromote);
                        if(block != null) {
+                               nodeStats.avgStoreSuccess.report(loc);
+                               if (dist > nodeStats.furthestStoreSuccess)
+                                       nodeStats.furthestStoreSuccess=dist;
                                return block;
                        }
-                       return sskDatacache.fetch(key, dontPromote);
+                       block=sskDatacache.fetch(key, dontPromote);
+                       if (block != null) {
+                               nodeStats.avgCacheSuccess.report(loc);
+                               if (dist > nodeStats.furthestCacheSuccess)
+                                       nodeStats.furthestCacheSuccess=dist;
+                       }
+                       return block;
                } catch (IOException e) {
                        Logger.error(this, "Cannot fetch data: "+e, e);
                        return null;
@@ -1781,9 +1793,23 @@
        public CHKBlock fetch(NodeCHK key, boolean dontPromote) {
                if(logMINOR) dumpStoreHits();
                try {
+                       double loc=key.toNormalizedDouble();
+                       double dist=Location.distance(lm.getLocation(), loc);
+                       nodeStats.avgRequestLocation.report(loc);
                        CHKBlock block = chkDatastore.fetch(key, dontPromote);
-                       if(block != null) return block;
-                       return chkDatacache.fetch(key, dontPromote);
+                       if (block != null) {
+                               nodeStats.avgStoreSuccess.report(loc);
+                               if (dist > nodeStats.furthestStoreSuccess)
+                                       nodeStats.furthestStoreSuccess=dist;
+                               return block;
+                       }
+                       block=chkDatacache.fetch(key, dontPromote);
+                       if (block != null) {
+                               nodeStats.avgCacheSuccess.report(loc);
+                               if (dist > nodeStats.furthestCacheSuccess)
+                                       nodeStats.furthestCacheSuccess=dist;
+                       }
+                       return block;
                } catch (IOException e) {
                        Logger.error(this, "Cannot fetch data: "+e, e);
                        return null;
@@ -1835,10 +1861,13 @@

        private void store(CHKBlock block, boolean deep) {
                try {
+                       double loc=block.getKey().toNormalizedDouble();
                        if(deep) {
                                chkDatastore.put(block);
+                               nodeStats.avgStoreLocation.report(loc);
                        }
                        chkDatacache.put(block);
+                       nodeStats.avgCacheLocation.report(loc);
                        if(clientCore != null && clientCore.requestStarters != 
null)
                                
clientCore.requestStarters.chkFetchScheduler.tripPendingKey(block);
                } catch (IOException e) {
@@ -2498,6 +2527,10 @@
          return usm;
        }

+       public LocationManager getLocationManager() {
+               return lm;
+       }
+       
        public int getSwaps() {
                return LocationManager.swaps;
        }

Modified: trunk/freenet/src/freenet/node/NodeStats.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeStats.java       2007-12-12 18:16:09 UTC 
(rev 16507)
+++ trunk/freenet/src/freenet/node/NodeStats.java       2007-12-12 21:00:27 UTC 
(rev 16508)
@@ -22,6 +22,7 @@
 import freenet.support.api.IntCallback;
 import freenet.support.api.LongCallback;
 import freenet.support.math.RunningAverage;
+import freenet.support.math.SimpleRunningAverage;
 import freenet.support.math.TimeDecayingRunningAverage;
 import freenet.support.math.TrivialRunningAverage;

@@ -144,8 +145,17 @@
        // various metrics
        public final RunningAverage routingMissDistance;
        public final RunningAverage backedOffPercent;
+       public final RunningAverage avgCacheLocation;
+       public final RunningAverage avgStoreLocation;
+       public final RunningAverage avgCacheSuccess;
+       public final RunningAverage avgStoreSuccess;
+       // FIXME: does furthest{Store,Cache}Success need to be synchronized?
+       public double furthestCacheSuccess=0.0;
+       public double furthestStoreSuccess=0.0;
        protected final Persister persister;

+       protected final RunningAverage avgRequestLocation;
+       
        // ThreadCounting stuffs
        public final ThreadGroup rootThreadGroup;
        private int threadLimit;
@@ -176,6 +186,14 @@
                this.hardRandom = node.random;
                this.routingMissDistance = new TimeDecayingRunningAverage(0.0, 
180000, 0.0, 1.0, node);
                this.backedOffPercent = new TimeDecayingRunningAverage(0.0, 
180000, 0.0, 1.0, node);
+               // FIXME PLEASE remove (int) casts
+               double nodeLoc=node.lm.getLocation();
+               this.avgCacheLocation=new 
SimpleRunningAverage((int)node.maxCacheKeys, nodeLoc);
+               this.avgStoreLocation=new 
SimpleRunningAverage((int)node.maxStoreKeys, nodeLoc);
+               // FIXME average for success-location may not need to be so 
large as the store.
+               this.avgCacheSuccess=new SimpleRunningAverage(10000, nodeLoc);
+               this.avgStoreSuccess=new SimpleRunningAverage(10000, nodeLoc);
+               this.avgRequestLocation=new SimpleRunningAverage(10000, 
nodeLoc);
                preemptiveRejectReasons = new StringCounter();
                localPreemptiveRejectReasons = new StringCounter();
                pInstantRejectIncoming = new TimeDecayingRunningAverage(0, 
60000, 0.0, 1.0, node);
@@ -186,6 +204,18 @@
                        new TimeDecayingRunningAverage(1, 10*60*1000 /* should 
be significantly longer than a typical transfer */, 0, Long.MAX_VALUE, node);
                nodePinger = new NodePinger(node);

+               // FIXME: data-store/cache averages need to be persisted to be 
valuable (or scanned at every launch).
+               /*
+               if (node.isAdvancedModeEnabled()) {
+                       //Uggghh....
+                       System.err.println("Scanning datastore/cache for 
location values");
+                       chkDatastore.kludgeScan(avgStoreLocation);
+                       sskDatastore.kludgeScan(avgStoreLocation);
+                       chkDatacache.kludgeScan(avgCacheLocation);
+                       sskDatacache.kludgeScan(avgCacheLocation);
+               }
+               */
+               
                previous_input_stat = 0;
                previous_output_stat = 0;
                previous_io_stat_time = 1;


Reply via email to