private void ModifyWeights( AggregatedClusterStatistic aggregatedClusterStatistic, IRelativeWeightCalculator relativeWeightCalculator, IWeightsNormalizer weightsNormalizer, IWeights weights) { var newWeights = new Dictionary <Uri, Weight>(aggregatedClusterStatistic.Replicas.Count); var statisticCollectedTimestamp = aggregatedClusterStatistic.Cluster.Timestamp; var relativeMaxWeight = 0d; foreach (var(replica, replicaStatistic) in aggregatedClusterStatistic.Replicas) { var previousWeight = weights.Get(replica, settings.WeightsTTL) ?? new Weight(settings.InitialWeight, statisticCollectedTimestamp - settings.WeightUpdatePeriod); var newReplicaWeight = relativeWeightCalculator .Calculate(aggregatedClusterStatistic.Cluster, replicaStatistic, previousWeight, settings); newWeights.Add(replica, newReplicaWeight); if (relativeMaxWeight < newReplicaWeight.Value) { relativeMaxWeight = newReplicaWeight.Value; } } weightsNormalizer.Normalize(newWeights, relativeMaxWeight); LogWeights(weights, newWeights); weights.Update(newWeights, settings); }
public void Update(AggregatedClusterStatistic snapshot, TimeSpan statisticTTL) { if (currentHistory == null) { currentHistory = snapshot; return; } var newReplicas = new HashSet <Uri>(snapshot.Replicas.Keys); var replicasUpdatedHistory = new Dictionary <Uri, AggregatedStatistic>(snapshot.Replicas.Count); var currentTime = DateTime.UtcNow; foreach (var(currentReplica, currentStatistic) in currentHistory.Replicas) { if (snapshot.Replicas.ContainsKey(currentReplica)) { replicasUpdatedHistory[currentReplica] = snapshot.Replicas[currentReplica]; newReplicas.Remove(currentReplica); continue; } if (currentTime - currentStatistic.Timestamp < statisticTTL) { replicasUpdatedHistory[currentReplica] = currentStatistic; } } foreach (var newReplica in newReplicas) { replicasUpdatedHistory[newReplica] = snapshot.Replicas[newReplica]; } currentHistory = new AggregatedClusterStatistic(snapshot.Cluster, replicasUpdatedHistory); }
public AggregatedClusterStatistic GetPenalizedAndSmoothedStatistic(DateTime currentTime, AggregatedClusterStatistic previous, int penaltyMultiplier, TimeSpan smoothingConstant) { var penalty = CalculatePenalty(penaltyMultiplier); var smoothedAggregatedClusterStatistic = clusterStatistic .Penalize(penalty) .Aggregate(currentTime) .Smooth(previous?.Cluster, smoothingConstant); var replicasSmoothedAggregatedStatistic = new Dictionary <Uri, AggregatedStatistic>(replicasStatistic.Count); foreach (var(replica, statisticBucket) in replicasStatistic) { var replicaSmoothedStatistic = statisticBucket .Penalize(penalty) .Aggregate(currentTime) .Smooth(GetReplicaStatisticHistory(replica), smoothingConstant); replicasSmoothedAggregatedStatistic.Add(replica, replicaSmoothedStatistic); } return(new AggregatedClusterStatistic(smoothedAggregatedClusterStatistic, replicasSmoothedAggregatedStatistic)); AggregatedStatistic?GetReplicaStatisticHistory(Uri replica) { if (previous == null || !previous.Replicas.TryGetValue(replica, out var statistic)) { return(null); } return(statistic); } }