Beispiel #1
0
        /// <summary>
        /// Adds an old value with a fixed timestamp to the reservoir.
        /// </summary>
        /// <param name="value">the value to be added</param>
        /// <param name="timestamp">the epoch timestamp of value in seconds</param>
        public void Update(long value, long timestamp)
        {
            rescaleIfNeeded();
            lockForRegularUsage();
            _lock.EnterReadLock();
            try
            {
                var            itemWeight = Weight(timestamp - _startTime);
                WeightedSample sample     = new WeightedSample(value, itemWeight);
                var            random     = ThreadLocalRandom.NextNonzeroDouble();
                var            priority   = itemWeight / random;

                var newCount = _count.IncrementAndGet();

                if (newCount <= _size)
                {
                    _values.AddOrUpdate(priority, sample, (p, v) => v);
                }
                else
                {
                    var first = _values.Keys.Min();
                    if (first < priority)
                    {
                        _values.AddOrUpdate(priority, sample, (p, v) => v);

                        WeightedSample removed;
                        while (!_values.TryRemove(first, out removed))
                        {
                            first = _values.Keys.First();
                        }
                    }
                }
            }
            finally
            {
                unlockForRegularUsage();
                _lock.ExitReadLock();
            }
        }
Beispiel #2
0
 /// <summary>
 /// Adds a recorded value
 /// </summary>
 /// <param name="value">the length of the value</param>
 public void Update(long value)
 {
     count.IncrementAndGet();
     reservoir.Update(value);
 }