Ticket #765 - optimize locking during profile reorg

This commit is contained in:
zab
2012-11-21 15:45:38 +00:00
parent 5f4562467e
commit 33ee8a38ca
2 changed files with 62 additions and 24 deletions

View File

@@ -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); }

View File

@@ -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++;
}