To keep O(1) insertion (with removal of the oldest item past 100) and O(1) lookups, you'll need a class that implements IDictionary and keeps an internal ordered list. If memory is more a concern, a BST implementation like SortedList
could be more appropriate. Anyway, your class will contain both a T[]
and a Dictionary<T,K>
(or SortedList<T,K>
). Do your own circular buffer indexing (easy), and keep both collections current in the add, remove, etc. methods. You'll have:
- O(1) enqueue (to back)
- O(n) insertion that violates order of adding (since you have to keep the array up to date); you'll likely never need this anyway
- O(1) dequeue (from front)
- O(1) or O(log n) keyed lookup
Make it generic and implement IDictionary<T,K>
and IDictionary
since there's no reason not to and you'll get an edge in performance.
One major consideration: what do you do about duplicate keys? I'm assuming you can't actually keep the duplicates, so:
- Throw an exception (if there are never duplicate keys, so it's simply an error to insert something twice)
- Move to back: check the
Count
of the dictionary, then insert the key using the this[key]
indexer. if the size increases, then check if the list already has the maximum capacity, remove the front item from the list and dictionary and add the new item to the back. If the dictionary did not increase in size, move the item from its existing place in the list to the back of the list.
- Overwrite without moving: The same as the previous item, but you don't have to mess with the list.
Finally, note that the internal list keeps keys, not values. This is to ensure O(1) dequeue when the list capacity is exceeded.