[freenet-dev] [freenet-cvs] r16508 - in trunk/freenet/src/freenet: clients/http node

Matthew Toseland toad at amphibian.dyndns.org
Thu Dec 13 22:31:34 UTC 2007


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 : http://emu.freenetproject.org/pipermail/devl/attachments/20071213/51c98613/attachment.pgp 


More information about the Devl mailing list