LRI (Least Recently Inserted)

I just recently had the need for a fairly specific piece of functionality in Node, but I couldn't seem to find anything that quite fit the bill. All I needed was a really simple collection that maintained up to a defined number of elements, and once that defined number had been reached, evicted the oldest element in the cache.

TL;DR: I've created a library, lri, to solve this if you just want to use it.

Use Cases

Seems simple right? I couldn't seem to find anything that fit that bill precisely. The rub lies with how "oldest" is defined. In my case, I wanted "oldest" to be defined as the oldest element inserted into the collection.
After thinking about it for a few minutes, it's not actually an uncommon use case. I immediately thought of two common use cases:

  1. An application needs to keep a finite collection of a user's actions, such as the undo and/or redo functionality.
  2. A program needs a finite collection of data points for calculations, such as the last 50 tick prices of a given stock.

These seem like fairly common use cases, so I'm not sure why nothing (easily findable) has been written to solve this issue.

Research

The LRU from Collectionsjs came close to fitting the bill, but it's based on mathematical set logic, which means that it will filter out any duplicate values that are inserted. Shoot! That won't work for either of the use-cases above.

LRI Implementation

After some brief contemplation, I decided just to write a simple wrapper around JavaScript's Native Array functionality to accomplish this. Enter lri, which can be installed via npm. Since this collection is a wrapper around the native array functionality with a little extra spice, I closely mimicked the contract of Array.

The Interface

Creating a new lri collection is as simple as invoking the constructor with a numeric argument that defines the maximum number of elements to retain in the collection:

var LRI = require('lri'),  
    lri;

lri = new LRI(10);  

To insert a new element into the lri collection, it's as simple as:

lri.unshift(1);  

If the number of elements in the LRI collection has reached the maximum (in the example above, the maximum has been defined as 10), the oldest value inserted into the collection is evicted and returned.

The interface exposes the slice() function in the event that a portion of or the entire collection is needed:

var lriArray = lri.slice();  

You can easily operate on the entire collection (be careful about making changes as this is a shallow copy) with common Array functionality:

lriArray.forEach(function() {  
    // Do something awesome here!
}, this);

Feel free to leave feedback or ask questions through the project's GitHub page. Enjoy!