/// <summary> /// Adds a new recorded value to the sample /// </summary> public void Update(long value) { var count = _count.IncrementAndGet(); if (count <= _values.Length) { var index = (int)count - 1; Interlocked.Exchange(ref _values[index], value); } else { var random = Math.Abs(Random.NextLong()) % count; if (random < _values.Length) { var index = (int)random; Interlocked.Exchange(ref _values[index], value); } } }
private void Update(long value, long timestamp) { _lock.EnterReadLock(); try { var priority = Weight(timestamp - _startTime) / Random.NextLong(); var newCount = _count.IncrementAndGet(); if (newCount <= _reservoirSize) { _values.AddOrUpdate(priority, value, (p, v) => v); } else { var first = _values.Keys.First(); if (first < priority) { _values.AddOrUpdate(priority, value, (p, v) => v); long removed; while (!_values.TryRemove(first, out removed)) { first = _values.Keys.First(); } } } } finally { _lock.ExitReadLock(); } var now = DateTime.Now.Ticks; var next = _nextScaleTime.Get(); if (now >= next) { Rescale(now, next); } }