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);
        }
Example #2
0
        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);
            }
        }