Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/lukeed/flru
A tiny (215B) and fast Least Recently Used (LRU) cache
https://github.com/lukeed/flru
Last synced: 16 days ago
JSON representation
A tiny (215B) and fast Least Recently Used (LRU) cache
- Host: GitHub
- URL: https://github.com/lukeed/flru
- Owner: lukeed
- License: mit
- Created: 2018-12-31T23:01:52.000Z (almost 6 years ago)
- Default Branch: master
- Last Pushed: 2019-07-11T19:26:23.000Z (over 5 years ago)
- Last Synced: 2024-04-14T11:43:49.676Z (7 months ago)
- Language: JavaScript
- Homepage:
- Size: 11.7 KB
- Stars: 309
- Watchers: 6
- Forks: 4
- Open Issues: 1
-
Metadata Files:
- Readme: readme.md
- License: license
Awesome Lists containing this project
README
# flru [![Build Status](https://travis-ci.org/lukeed/flru.svg?branch=master)](https://travis-ci.org/lukeed/flru)
> A tiny (215B) and fast Least Recently Used (LRU) cache
Internally, two caches are kept. This is because it's far more performant to swap (and maintain) dictionaries than it is to `delete`/purge keys on every read/write interaction. Because of this, `flru` will store `2n` items in memory, where `n` is the [`max`](#max) limit. In practice, this means that with `max=3` and items `(a, b, c)` already written, writing a `d` value ***will not*** automatically purge the `a` key. Instead, `a` _can_ be retrieved, which would move it to the "active" cache. It's only when this "active" half exceeds the `max` that the "stale" half is purged.
> See [Usage](#Usage) for a visual explanation~!
This implementation is optimized for all-around performance – reads, writes, updates, and evictions.
This module is available in three formats:
* **ES Module**: `dist/flru.mjs`
* **CommonJS**: `dist/flru.js`
* **UMD**: `dist/flru.min.js`## Install
```
$ npm install --save flru
```## Usage
```js
// Legend:
// S => the stale cache
// A => the active cacheconst flru = require('flru');
let cache = flru(3); // A=[] S=[]
cache.set('a', 1); // A=[a] S=[]
cache.set('b', 2); // A=[a,b] S=[]
cache.set('b', 9); // A=[a,b] S=[]
cache.set('c', 3); // A=[a,b,c] S=[]cache.has('a'); //=> true
cache.set('d', 4); // A=[d] S=[a,b,c]
cache.get('a'); // A=[d,a] S=[a,b,c]
cache.set('e', 5); // A=[d,a,e] S=[a,b,c]
cache.get('a'); // A=[d,a,e] S=[a,b,c]
cache.get('c'); // A=[c] S=[d,a,e]cache.has('c'); //=> true
cache.has('b'); //=> false
cache.has('a'); //=> truecache.clear(); // A=[] S=[]
```## API
### flru(max)
return `Object`Initialize a new `flru` cache instance.
#### max
Required: `true`
Type: `Number`
Default: `1`The maximum number of items to maintain – must be a positive, non-zero integer!
> **Important:** The default value is pointless and will result in excessive computation. It's there only to avoid memory leak!
### flru.has(key)
Return: `Boolean`Check if the cache has the given key.
#### key
Type: `String`The key name to check.
### flru.get(key)
Return: `Mixed`Get the assigned value for a given key. Will return `undefined` if the cache has evicted `key` or never contained it.
#### key
Type: `String`The item's unique name / identifier.
### flru.set(key, value)
Return: `undefined`Persist an item to the cache by a given `key` name.
#### key
Type: `String`The item's unique name / identifier.
#### value
Type: `Mixed`The item's value to be cached.
### flru.clear(keepOld)
Return: `undefined`Reset the cache(s) and counter.
#### keepOld
Type: `Boolean`
Default: `false`When `true`, preserves the stale/outgoing cache.
> **Important:** This is used internally & generally should be ignored!
## Benchmarks
You can find benchmarks in the [`bench`]() directory. They are setup to run one library at a time so that there's no cross-contamination of memory management or Node's runtime caching.
* `set` – writing values into _new_ keys
* `update` – updating values into _existing_ keys
* `evict` – writing `2 * limit` keys to the cache, forcing eviction> Results below are with Node v10.13.0
```
# set()
flru x 45,261 ops/sec ±1.63% (94 runs sampled)
lru-cache x 14,240 ops/sec ±5.70% (85 runs sampled)
tmp-cache x 8,229 ops/sec ±3.06% (83 runs sampled)
tiny-lru x 24,415 ops/sec ±2.48% (91 runs sampled)# get()
flru x 78,585 ops/sec ±1.70% (98 runs sampled)
lru-cache x 27,409 ops/sec ±2.64% (93 runs sampled)
tmp-cache x 6,229 ops/sec ±1.06% (87 runs sampled)
tiny-lru x 20,313 ops/sec ±2.01% (96 runs sampled)# has()
flru x 79,843 ops/sec ±1.35% (97 runs sampled)
lru-cache x 31,354 ops/sec ±2.87% (90 runs sampled)
tmp-cache x 813,828 ops/sec ±64.67% (95 runs sampled)
tiny-lru x 128,250 ops/sec ±3.73% (93 runs sampled)# update()
flru x 44,885 ops/sec ±1.86% (95 runs sampled)
lru-cache x 15,616 ops/sec ±2.46% (94 runs sampled)
tmp-cache x 8,529 ops/sec ±0.85% (87 runs sampled)
tiny-lru x 23,060 ops/sec ±2.72% (93 runs sampled)# evict()
flru x 8,258 ops/sec ±1.48% (88 runs sampled)
lru-cache x 1,492 ops/sec ±2.60% (77 runs sampled)
tmp-cache x 836 ops/sec ±0.59% (95 runs sampled)
tiny-lru x 2,626 ops/sec ±2.61% (81 runs sampled)
```## Related
- [tmp-cache](https://github.com/lukeed/tmp-cache) - Full-featured (but slower) alternative, supporting time-sensitive expirations.
- [`tiny-lru`](https://github.com/avoidwork/tiny-lru) - Same as `tmp-cache` but significantly faster.## License
MIT © [Luke Edwards](https://lukeed.com)