Okay, this is good on the whole, but you are right, the memory usage is 
unacceptable. You should use a cheaper running average; 
BootstrappingDecayingRunningAverage is the obvious thing (a klein filter 
whose parameter starts off at 1.0 and decays until it reaches a certain 
point), but if you want something more conventional, make something that just 
keeps counters; you know what value you are removing when a key is removed 
from the store.

On Wednesday 12 December 2007 21:00, you wrote:
> 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;
> 
> _______________________________________________
> cvs mailing list
> cvs at freenetproject.org
> http://emu.freenetproject.org/cgi-bin/mailman/listinfo/cvs
> 
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: 
<https://emu.freenetproject.org/pipermail/devl/attachments/20071213/51c98613/attachment.pgp>

Reply via email to