Beispiel #1
0
        /// <summary>Try to remove extraneous items from the set of sampled items.</summary>
        /// <remarks>
        /// Try to remove extraneous items from the set of sampled items. This checks
        /// if an item is unnecessary based on the desired error bounds, and merges it
        /// with the adjacent item if it is.
        /// </remarks>
        private void Compress()
        {
            if (samples.Count < 2)
            {
                return;
            }
            ListIterator <SampleQuantiles.SampleItem> it = samples.ListIterator();

            SampleQuantiles.SampleItem prev = null;
            SampleQuantiles.SampleItem next = it.Next();
            while (it.HasNext())
            {
                prev = next;
                next = it.Next();
                if (prev.g + next.g + next.delta <= AllowableError(it.PreviousIndex()))
                {
                    next.g += prev.g;
                    // Remove prev. it.remove() kills the last thing returned.
                    it.Previous();
                    it.Previous();
                    it.Remove();
                    // it.next() is now equal to next, skip it back forward again
                    it.Next();
                }
            }
        }
Beispiel #2
0
        /// <summary>Merges items from buffer into the samples array in one pass.</summary>
        /// <remarks>
        /// Merges items from buffer into the samples array in one pass.
        /// This is more efficient than doing an insert on every item.
        /// </remarks>
        private void InsertBatch()
        {
            if (bufferCount == 0)
            {
                return;
            }
            Arrays.Sort(buffer, 0, bufferCount);
            // Base case: no samples
            int start = 0;

            if (samples.Count == 0)
            {
                SampleQuantiles.SampleItem newItem = new SampleQuantiles.SampleItem(buffer[0], 1,
                                                                                    0);
                samples.AddItem(newItem);
                start++;
            }
            ListIterator <SampleQuantiles.SampleItem> it = samples.ListIterator();

            SampleQuantiles.SampleItem item = it.Next();
            for (int i = start; i < bufferCount; i++)
            {
                long v = buffer[i];
                while (it.NextIndex() < samples.Count && item.value < v)
                {
                    item = it.Next();
                }
                // If we found that bigger item, back up so we insert ourselves before it
                if (item.value > v)
                {
                    it.Previous();
                }
                // We use different indexes for the edge comparisons, because of the above
                // if statement that adjusts the iterator
                int delta;
                if (it.PreviousIndex() == 0 || it.NextIndex() == samples.Count)
                {
                    delta = 0;
                }
                else
                {
                    delta = ((int)Math.Floor(AllowableError(it.NextIndex()))) - 1;
                }
                SampleQuantiles.SampleItem newItem = new SampleQuantiles.SampleItem(v, 1, delta);
                it.Add(newItem);
                item = newItem;
            }
            bufferCount = 0;
        }
Beispiel #3
0
        /// <summary>Get the estimated value at the specified quantile.</summary>
        /// <param name="quantile">Queried quantile, e.g. 0.50 or 0.99.</param>
        /// <returns>Estimated value at that quantile.</returns>
        private long Query(double quantile)
        {
            Preconditions.CheckState(!samples.IsEmpty(), "no data in estimator");
            int rankMin = 0;
            int desired = (int)(quantile * count);
            ListIterator <SampleQuantiles.SampleItem> it = samples.ListIterator();

            SampleQuantiles.SampleItem prev = null;
            SampleQuantiles.SampleItem cur  = it.Next();
            for (int i = 1; i < samples.Count; i++)
            {
                prev     = cur;
                cur      = it.Next();
                rankMin += prev.g;
                if (rankMin + cur.g + cur.delta > desired + (AllowableError(i) / 2))
                {
                    return(prev.value);
                }
            }
            // edge case of wanting max value
            return(samples[samples.Count - 1].value);
        }