//return the score by data
        //server with highest score will be choosen
        private float? GetScore(string identifier, List<StatisticsRecord> records)
        {
            var config = _controller.StatisticsConfiguration;
            float? score = null;

            var averageRecord = new StatisticsRecord(identifier,
                records.Where(record => record.MaxInboundSpeed != null).Select(record => record.MaxInboundSpeed.Value).ToList(),
                records.Where(record => record.MaxOutboundSpeed != null).Select(record => record.MaxOutboundSpeed.Value).ToList(),
                records.Where(record => record.AverageLatency != null).Select(record => record.AverageLatency.Value).ToList());
            averageRecord.SetResponse(records.Select(record => record.AverageResponse).ToList());

            foreach (var calculation in config.Calculations)
            {
                var name = calculation.Key;
                var field = typeof (StatisticsRecord).GetField(name);
                dynamic value = field?.GetValue(averageRecord);
                var factor = calculation.Value;
                if (value == null || factor.Equals(0)) continue;
                score = score ?? 0;
                score += value * factor;
            }

            if (score != null)
            {
                Logging.Debug($"Highest score: {score} {JsonConvert.SerializeObject(averageRecord, Formatting.Indented)}");
            }
            return score;
        }
 private bool IsValidRecord(StatisticsRecord record)
 {
     if (Config.ByHourOfDay)
     {
         if (!record.Timestamp.Hour.Equals(DateTime.Now.Hour)) return false;
     }
     return true;
 }
 private void AppendRecord(string serverIdentifier, StatisticsRecord record)
 {
     List<StatisticsRecord> records;
     if (!RawStatistics.TryGetValue(serverIdentifier, out records))
     {
         records = new List<StatisticsRecord>();
     }
     records.Add(record);
     RawStatistics[serverIdentifier] = records;
 }
        private async void UpdateRecords()
        {
            var records = new Dictionary<string, StatisticsRecord>();

            foreach (var server in _controller.GetCurrentConfiguration().configs)
            {
                var id = server.Identifier();
                List<int> inboundSpeedRecords = null;
                List<int> outboundSpeedRecords = null;
                List<int> latencyRecords = null;
                _inboundSpeedRecords.TryGetValue(id, out inboundSpeedRecords);
                _outboundSpeedRecords.TryGetValue(id, out outboundSpeedRecords);
                _latencyRecords.TryGetValue(id, out latencyRecords);
                StatisticsRecord record = new StatisticsRecord(id, inboundSpeedRecords, outboundSpeedRecords, latencyRecords);
                /* duplicate server identifier */
                if (records.ContainsKey(id))
                    records[id] = record;
                else
                    records.Add(id, record);
            }

            if (Config.Ping)
            {
                var icmpResults = await TaskEx.WhenAll(_controller.GetCurrentConfiguration().configs.Select(ICMPTest));
                foreach (var result in icmpResults.Where(result => result != null))
                {
                    records[result.Server.Identifier()].SetResponse(result.RoundtripTime);
                }
            }

            foreach (var kv in records.Where(kv => !kv.Value.IsEmptyData()))
            {
                AppendRecord(kv.Key, kv.Value);
            }
        }
        private void UpdateRecords()
        {
            var records = new Dictionary<string, StatisticsRecord>();
            UpdateRecordsState state = new UpdateRecordsState();
            state.counter = _controller.GetCurrentConfiguration().configs.Count;
            foreach (var server in _controller.GetCurrentConfiguration().configs)
            {
                var id = server.Identifier();
                List<int> inboundSpeedRecords = null;
                List<int> outboundSpeedRecords = null;
                List<int> latencyRecords = null;
                _inboundSpeedRecords.TryGetValue(id, out inboundSpeedRecords);
                _outboundSpeedRecords.TryGetValue(id, out outboundSpeedRecords);
                _latencyRecords.TryGetValue(id, out latencyRecords);
                StatisticsRecord record = new StatisticsRecord(id, inboundSpeedRecords, outboundSpeedRecords, latencyRecords);
                /* duplicate server identifier */
                if (records.ContainsKey(id))
                    records[id] = record;
                else
                    records.Add(id, record);
                if (Config.Ping)
                {
                    MyPing ping = new MyPing(server, Repeat);
                    ping.Completed += ping_Completed;
                    ping.Start(new PingState { state = state, record = record });
                }
                else if (!record.IsEmptyData())
                {
                    AppendRecord(id, record);
                }
            }

            if (!Config.Ping)
            {
                Save();
                FilterRawStatistics();
            }
        }
 private void AppendRecord(string serverIdentifier, StatisticsRecord record)
 {
     try
     {
         List<StatisticsRecord> records;
         lock (RawStatistics)
         {
             if (!RawStatistics.TryGetValue(serverIdentifier, out records))
             {
                 records = new List<StatisticsRecord>();
                 RawStatistics[serverIdentifier] = records;
             }
         }
         records.Add(record);
     }
     catch (Exception e)
     {
         Logging.LogUsefulException(e);
     }
 }