From 33ee8a38caa7f94c40f479404a7964f9e501086f Mon Sep 17 00:00:00 2001 From: zab <zab@mail.i2p> Date: Wed, 21 Nov 2012 15:45:38 +0000 Subject: [PATCH] Ticket #765 - optimize locking during profile reorg --- .../i2p/router/peermanager/PeerProfile.java | 60 +++++++++++++------ .../router/peermanager/ProfileOrganizer.java | 26 +++++--- 2 files changed, 62 insertions(+), 24 deletions(-) diff --git a/router/java/src/net/i2p/router/peermanager/PeerProfile.java b/router/java/src/net/i2p/router/peermanager/PeerProfile.java index 68b4629b46..476f549c50 100644 --- a/router/java/src/net/i2p/router/peermanager/PeerProfile.java +++ b/router/java/src/net/i2p/router/peermanager/PeerProfile.java @@ -54,6 +54,13 @@ public class PeerProfile { private double _capacityValue; private double _integrationValue; private boolean _isFailing; + // new calculation values, to be updated + private double _speedValueNew; + private double _capacityValueNew; + private double _integrationValueNew; + private boolean _isFailingNew; + // are we in coalescing state? + private boolean _coalescing; // good vs bad behavior private TunnelHistory _tunnelHistory; private DBHistory _dbHistory; @@ -500,28 +507,47 @@ public class PeerProfile { /** update the stats and rates (this should be called once a minute) */ public void coalesceStats() { if (!_expanded) return; - //_receiveSize.coalesceStats(); - //_sendSuccessSize.coalesceStats(); - _tunnelCreateResponseTime.coalesceStats(); - _tunnelTestResponseTime.coalesceStats(); - _tunnelHistory.coalesceStats(); - if (_expandedDB) { - _dbIntroduction.coalesceStats(); - _dbResponseTime.coalesceStats(); - _dbHistory.coalesceStats(); - } - - coalesceThroughput(); - - _speedValue = calculateSpeed(); - _capacityValue = calculateCapacity(); - _integrationValue = calculateIntegration(); - _isFailing = calculateIsFailing(); + + coalesceOnly(); + updateValues(); if (_log.shouldLog(Log.DEBUG)) _log.debug("Coalesced: speed [" + _speedValue + "] capacity [" + _capacityValue + "] integration [" + _integrationValue + "] failing? [" + _isFailing + "]"); } + void coalesceOnly() { + _coalescing = true; + + //_receiveSize.coalesceStats(); + //_sendSuccessSize.coalesceStats(); + _tunnelCreateResponseTime.coalesceStats(); + _tunnelTestResponseTime.coalesceStats(); + _tunnelHistory.coalesceStats(); + if (_expandedDB) { + _dbIntroduction.coalesceStats(); + _dbResponseTime.coalesceStats(); + _dbHistory.coalesceStats(); + } + + coalesceThroughput(); + + _speedValueNew = calculateSpeed(); + _capacityValueNew = calculateCapacity(); + _integrationValueNew = calculateIntegration(); + _isFailingNew = calculateIsFailing(); + } + + void updateValues() { + if (!_coalescing) // can happen + coalesceOnly(); + _coalescing = false; + + _speedValue = _speedValueNew; + _capacityValue = _capacityValueNew; + _integrationValue = _integrationValueNew; + _isFailing = _isFailingNew; + } + private double calculateSpeed() { return SpeedCalculator.calc(this); } private double calculateCapacity() { return CapacityCalculator.calc(this); } private double calculateIntegration() { return IntegrationCalculator.calc(this); } diff --git a/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java b/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java index bd834c7b92..c7e45262b2 100644 --- a/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java +++ b/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java @@ -780,7 +780,24 @@ public class ProfileOrganizer { // drop profiles that we haven't spoken to in a while expireOlderThan = _context.clock().now() - _currentExpireTime; } - + + if (shouldCoalesce) { + getReadLock(); + try { + for (Iterator<PeerProfile> iter = _strictCapacityOrder.iterator(); iter.hasNext(); ) { + PeerProfile prof = iter.next(); + if ( (expireOlderThan > 0) && (prof.getLastSendSuccessful() <= expireOlderThan) ) { + continue; + } + long coalesceStart = System.currentTimeMillis(); + prof.coalesceOnly(); + coalesceTime += (int)(System.currentTimeMillis()-coalesceStart); + } + } finally { + releaseReadLock(); + } + } + if (!getWriteLock()) return; long start = System.currentTimeMillis(); @@ -800,12 +817,7 @@ public class ProfileOrganizer { continue; // drop, but no need to delete, since we don't periodically reread // TODO maybe we should delete files, otherwise they are only deleted at restart } - - if (shouldCoalesce) { - long coalesceStart = System.currentTimeMillis(); - prof.coalesceStats(); - coalesceTime += (int)(System.currentTimeMillis()-coalesceStart); - } + prof.updateValues(); reordered.add(prof); profileCount++; } -- GitLab