react-relay
Version:
A framework for building GraphQL-driven React applications.
99 lines (83 loc) • 2.14 kB
Flow
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
* @oncall relay
*/
'use strict';
const invariant = require('invariant');
export interface Cache<T> {
get(key: string): ?T;
set(key: string, value: T): void;
has(key: string): boolean;
delete(key: string): void;
size(): number;
capacity(): number;
clear(): void;
}
/**
* JS maps (both plain objects and Map) maintain key insertion
* order, which means there is an easy way to simulate LRU behavior
* that should also perform quite well:
*
* To insert a new value, first delete the key from the inner _map,
* then _map.set(k, v). By deleting and reinserting, you ensure that the
* map sees the key as the last inserted key.
*
* Get does the same: if the key is present, delete and reinsert it.
*/
class LRUCache<T> implements Cache<T> {
_capacity: number;
_map: Map<string, T>;
constructor(capacity: number) {
this._capacity = capacity;
invariant(
this._capacity > 0,
'LRUCache: Unable to create instance of cache with zero or negative capacity.',
);
this._map = new Map();
}
set(key: string, value: T): void {
this._map.delete(key);
this._map.set(key, value);
if (this._map.size > this._capacity) {
const firstKey = this._map.keys().next();
if (!firstKey.done) {
this._map.delete(firstKey.value);
}
}
}
get(key: string): ?T {
const value = this._map.get(key);
if (value != null) {
this._map.delete(key);
this._map.set(key, value);
}
return value;
}
has(key: string): boolean {
return this._map.has(key);
}
delete(key: string): void {
this._map.delete(key);
}
size(): number {
return this._map.size;
}
capacity(): number {
return this._capacity - this._map.size;
}
clear(): void {
this._map.clear();
}
}
function create<T>(capacity: number): LRUCache<T> {
return new LRUCache<T>(capacity);
}
module.exports = {
create,
};