At a minimum, you will need to maintain a queue of the last 1000 items.
To maintain the average value, maintain the total number of the last 1000 elements; when you add a new item to the queue, you add its value to the total amount, and also subtract the value of the oldest item that you just removed from the queue. Return the total divided by 1000 and there you go.
To maintain the current Nth percentile, maintain two heaps and keep the number of elements in heaps; the βbottomβ heap has a lower N% value, and the βtopβ heap has a top (1-N)% (for example, the bottom 95th percentile heap will have 950 items, and the top fifth percentile heap will have 50 items). At any time, you can return the lowest element from the top heap and your percentile. When you remove an item from the last value queue, also remove the value from the heap. If this leaves the heaps unbalanced (for example, the lower heap has 951 elements and the upper heap has 49 elements), then shift the elements to balance them (for example, remove the upper element from the lower heap and add it to the upper heap).
Since you want two percentiles, use three heaps β the bottom heap has the bottom 950 elements, the middle one has 40, and the top one has the highest 10. Return the lowest element of the middle heap for the 95th percentile, and the lowest element of the upper heap for 99- th percentile.
Adding and removing heap elements is O (lg (n)), so this is the cost of adding a new element to the queue and three heaps: remove the oldest queue element from heaps (O (lg (n)), add the new queue element to corresponding heap (O (lg (n)) and, if necessary, compare heaps (again, O (lg (n)). Add a new element to the lowest heap whose senior element is larger than the heap element, i.e.
if (newElement < lowestHeap.maxElement) { lowestHeap.add(newElement) } else if (newElement < middleHeap.maxElement) { middleHeap.add(newElement) } else { highestHeap.add(newElement) }
Make sure your heaps allow duplicate items
Zim-Zam O'Pootertoot
source share