From 60048ff669a746751983b219d40eb4915ae92909 Mon Sep 17 00:00:00 2001 From: Wes Roberts Date: Tue, 9 Jun 2020 19:02:17 -0400 Subject: [PATCH 1/5] RrMapCache and RrObjectCache --- .../bundles-snapshot.test.js.snap | 123 ++++++++++++++++++ src/cache/README.md | 5 +- src/cache/RrMapCache.js | 41 ++++++ src/cache/RrObjectCache.js | 44 +++++++ src/cache/__tests__/RrMapCache.spec.js | 12 ++ src/cache/__tests__/RrObjectCache.spec.js | 12 ++ src/cache/__util__/testBasicBehavior.js | 5 + src/cache/__util__/testRrBehavior.js | 30 +++++ src/index.d.ts | 17 +++ src/index.js | 2 + 10 files changed, 290 insertions(+), 1 deletion(-) create mode 100644 src/cache/RrMapCache.js create mode 100644 src/cache/RrObjectCache.js create mode 100644 src/cache/__tests__/RrMapCache.spec.js create mode 100644 src/cache/__tests__/RrObjectCache.spec.js create mode 100644 src/cache/__util__/testRrBehavior.js diff --git a/jest/__snapshots__/bundles-snapshot.test.js.snap b/jest/__snapshots__/bundles-snapshot.test.js.snap index c8ffbd89..d3d2b40f 100644 --- a/jest/__snapshots__/bundles-snapshot.test.js.snap +++ b/jest/__snapshots__/bundles-snapshot.test.js.snap @@ -370,12 +370,135 @@ exports[`Dist bundle is unchanged 1`] = ` return LruMapCache; }(); + var RrObjectCache = /*#__PURE__*/function () { + function RrObjectCache(_temp) { + var _ref = _temp === void 0 ? {} : _temp, + cacheSize = _ref.cacheSize; + + validateCacheSize(cacheSize); + this._cache = {}; + this._cacheKeys = []; + this._cacheLength = 0; + this._cacheSize = cacheSize; + } + + var _proto = RrObjectCache.prototype; + + _proto.set = function set(key, selectorFn) { + if (this._cacheLength >= this._cacheSize) { + this._randomReplace(key, selectorFn); + } else { + this._cache[key] = selectorFn; + this._cacheKeys[this._cacheLength] = key; + this._cacheLength++; + } + }; + + _proto.get = function get(key) { + return this._cache[key]; + }; + + _proto.remove = function remove(key) { + var index = this._cacheKeys.indexOf(key); // O(1) + + + if (index > -1) { + delete this._cache[key]; + var lastIndex = this._cacheLength - 1; + var lastKey = this._cacheKeys[lastIndex]; + this._cacheKeys[index] = lastKey; + this._cacheLength--; + } + }; + + _proto.clear = function clear() { + this._cache = {}; + this._cacheKeys = []; + this._cacheLength = 0; + }; + + _proto._randomReplace = function _randomReplace(newKey, newValue) { + var index = Math.floor(Math.random() * this._cacheLength); + var key = this._cacheKeys[index]; + delete this._cache[key]; + this._cacheKeys[index] = newKey; + this._cache[newKey] = newValue; + }; + + _proto.isValidCacheKey = function isValidCacheKey(cacheKey) { + return isStringOrNumber(cacheKey); + }; + + return RrObjectCache; + }(); + + var RrMapCache = /*#__PURE__*/function () { + function RrMapCache(_temp) { + var _ref = _temp === void 0 ? {} : _temp, + cacheSize = _ref.cacheSize; + + validateCacheSize(cacheSize); + this.clear(); + this._cacheSize = cacheSize; + } + + var _proto = RrMapCache.prototype; + + _proto.set = function set(key, selectorFn) { + if (this._cacheLength >= this._cacheSize) { + this._randomReplace(key, selectorFn); + } else { + this._cache.set(key, selectorFn); + + this._cacheKeys[this._cacheLength] = key; + this._cacheLength++; + } + }; + + _proto.get = function get(key) { + return this._cache.get(key); + }; + + _proto.remove = function remove(key) { + var index = this._cacheKeys.indexOf(key); + + if (index > -1) { + delete this._cache[\\"delete\\"](key); + var lastIndex = this._cacheLength - 1; + var lastKey = this._cacheKeys[lastIndex]; + this._cacheKeys[index] = lastKey; + this._cacheLength--; + } + }; + + _proto.clear = function clear() { + this._cache = new Map(); + this._cacheKeys = []; + this._cacheLength = 0; + }; + + _proto._randomReplace = function _randomReplace(newKey, newValue) { + var index = Math.floor(Math.random() * this._cacheLength); + var key = this._cacheKeys[index]; + + this._cache[\\"delete\\"](key); + + this._cacheKeys[index] = newKey; + + this._cache.set(newKey, newValue); + }; + + return RrMapCache; + }(); + exports.FifoMapCache = FifoMapCache; exports.FifoObjectCache = FifoObjectCache; exports.FlatMapCache = FlatMapCache; exports.FlatObjectCache = FlatObjectCache; exports.LruMapCache = LruMapCache; exports.LruObjectCache = LruObjectCache; + exports.RrMapCache = RrMapCache; + exports.RrObjectCache = RrObjectCache; exports.createCachedSelector = createCachedSelector; exports.createStructuredCachedSelector = createStructuredCachedSelector; exports[\\"default\\"] = createCachedSelector; diff --git a/src/cache/README.md b/src/cache/README.md index 511dece9..014f8660 100644 --- a/src/cache/README.md +++ b/src/cache/README.md @@ -4,16 +4,18 @@ ## Available cache objects -`re-reselect` ships with **6 ready-to-use cache object constructors**: +`re-reselect` ships with several **ready-to-use cache object constructors**: | name | accepted cacheKey | type | storage | | :---------------------------------------: | :---------------: | :-----------------------------------: | :----------------------------: | | [`FlatObjectCache`](./FlatObjectCache.js) | `number` `string` | flat unlimited | JS object | | [`FifoObjectCache`](./FifoObjectCache.js) | `number` `string` | [first in first out][docs-fifo-cache] | JS object | | [`LruObjectCache`](./LruObjectCache.js) | `number` `string` | [least recently used][docs-lru-cache] | JS object | +| [`RrObjectCache`](./RrObjectCache.js) | `number` `string` | [random replacement][docs-rr-cache] | JS object | | [`FlatMapCache`](./FlatMapCache.js) | any | flat unlimited | [Map object][docs-mozilla-map] | | [`FifoMapCache`](./FifoMapCache.js) | any | [first in first out][docs-fifo-cache] | [Map object][docs-mozilla-map] | | [`LruMapCache`](./LruMapCache.js) | any | [least recently used][docs-lru-cache] | [Map object][docs-mozilla-map] | +| [`RrMapCache`](./RrMapCache.js) | any | [random replacement][docs-rr-cache] | [Map object][docs-mozilla-map] | ```js @@ -53,4 +55,5 @@ interface ICacheObject { [wiki-strategy-pattern]: https://en.wikipedia.org/wiki/Strategy_pattern [docs-fifo-cache]: https://en.wikipedia.org/wiki/Cache_replacement_policies#First_in_first_out_(FIFO) [docs-lru-cache]: https://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU) +[docs-rr-cache]: https://en.wikipedia.org/wiki/Cache_replacement_policies#Random_replacement_(RR) [docs-mozilla-map]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map diff --git a/src/cache/RrMapCache.js b/src/cache/RrMapCache.js new file mode 100644 index 00000000..cde4ad65 --- /dev/null +++ b/src/cache/RrMapCache.js @@ -0,0 +1,41 @@ +import validateCacheSize from './util/validateCacheSize'; +import isStringOrNumber from './util/isStringOrNumber'; + +export default class RrMapCache { + constructor({cacheSize} = {}) { + validateCacheSize(cacheSize); + this.clear(); + this._cacheSize = cacheSize; + } + set(key, selectorFn) { + if (this._cacheLength >= this._cacheSize) { + this._randomReplace(key, selectorFn); + } else { + this._cache.set(key, selectorFn); + this._cacheKeys[this._cacheLength] = key; + this._cacheLength++; + } + } + get(key) { + return this._cache.get(key); + } + remove(key) { + const index = this._cacheKeys.indexOf(key); // O(1) + if (index > -1) { + delete this._cache.delete(key); + this._cacheLength--; + this._cacheKeys[index] = this._cacheKeys[this._cacheLength]; + } + } + clear() { + this._cache = new Map(); + this._cacheKeys = []; + this._cacheLength = 0; + } + _randomReplace(newKey, newValue) { + const index = Math.floor(Math.random() * this._cacheLength); + this._cache.delete(this._cacheKeys[index]); + this._cacheKeys[index] = newKey; + this._cache.set(newKey, newValue); + } +} diff --git a/src/cache/RrObjectCache.js b/src/cache/RrObjectCache.js new file mode 100644 index 00000000..6440ed48 --- /dev/null +++ b/src/cache/RrObjectCache.js @@ -0,0 +1,44 @@ +import validateCacheSize from './util/validateCacheSize'; +import isStringOrNumber from './util/isStringOrNumber'; + +export default class RrObjectCache { + constructor({cacheSize} = {}) { + validateCacheSize(cacheSize); + this.clear(); + this._cacheSize = cacheSize; + } + set(key, selectorFn) { + if (this._cacheLength >= this._cacheSize) { + this._randomReplace(key, selectorFn); + } else { + this._cache[key] = selectorFn; + this._cacheKeys[this._cacheLength] = key; + this._cacheLength++; + } + } + get(key) { + return this._cache[key]; + } + remove(key) { + const index = this._cacheKeys.indexOf(key); // O(1) + if (index > -1) { + delete this._cache[key]; + this._cacheLength--; + this._cacheKeys[index] = this._cacheKeys[this._cacheLength]; + } + } + clear() { + this._cache = {}; + this._cacheKeys = []; + this._cacheLength = 0; + } + _randomReplace(newKey, newValue) { + const index = Math.floor(Math.random() * this._cacheLength); + delete this._cache[this._cacheKeys[index]]; + this._cacheKeys[index] = newKey; + this._cache[newKey] = newValue; + } + isValidCacheKey(cacheKey) { + return isStringOrNumber(cacheKey); + } +} diff --git a/src/cache/__tests__/RrMapCache.spec.js b/src/cache/__tests__/RrMapCache.spec.js new file mode 100644 index 00000000..f553b2cc --- /dev/null +++ b/src/cache/__tests__/RrMapCache.spec.js @@ -0,0 +1,12 @@ +import {RrMapCache as CacheObject} from '../../../src/index'; +import testBasicBehavior from '../__util__/testBasicBehavior'; +import testRrBehavior from '../__util__/testRrBehavior'; +import testCacheSizeOptionValidation from '../__util__/testCacheSizeOptionValidation'; +import testMapCacheKeyBehavior from '../__util__/testMapCacheKeyBehavior'; + +describe('RrMapCache', () => { + testBasicBehavior(CacheObject, {cacheSize: 10}); + testRrBehavior(CacheObject); + testCacheSizeOptionValidation(CacheObject); + testMapCacheKeyBehavior(CacheObject, {cacheSize: 10}); +}); diff --git a/src/cache/__tests__/RrObjectCache.spec.js b/src/cache/__tests__/RrObjectCache.spec.js new file mode 100644 index 00000000..4d69bf55 --- /dev/null +++ b/src/cache/__tests__/RrObjectCache.spec.js @@ -0,0 +1,12 @@ +import {RrObjectCache as CacheObject} from '../../../src/index'; +import testBasicBehavior from '../__util__/testBasicBehavior'; +import testRrBehavior from '../__util__/testRrBehavior'; +import testCacheSizeOptionValidation from '../__util__/testCacheSizeOptionValidation'; +import testObjectCacheKeyBehavior from '../__util__/testObjectCacheKeyBehavior'; + +describe('RrObjectCache', () => { + testBasicBehavior(CacheObject, {cacheSize: 10}); + testRrBehavior(CacheObject); + testCacheSizeOptionValidation(CacheObject); + testObjectCacheKeyBehavior(CacheObject, {cacheSize: 10}); +}); diff --git a/src/cache/__util__/testBasicBehavior.js b/src/cache/__util__/testBasicBehavior.js index 34d1284f..020c9c73 100644 --- a/src/cache/__util__/testBasicBehavior.js +++ b/src/cache/__util__/testBasicBehavior.js @@ -36,6 +36,11 @@ function testBasicBehavior(CacheObject, options) { expect(cache.get(entry)).toBe(undefined); }); }); + + it('removes non-existant keys', () => { + const cache = new CacheObject({cacheSize: 5}); + expect(() => cache.remove('foo')).not.toThrow(); + }); }); } diff --git a/src/cache/__util__/testRrBehavior.js b/src/cache/__util__/testRrBehavior.js new file mode 100644 index 00000000..30efc15d --- /dev/null +++ b/src/cache/__util__/testRrBehavior.js @@ -0,0 +1,30 @@ +import fillCacheWith from './fillCacheWith'; + +function testRrBehavior(CacheObject) { + describe('RR cache behavior', () => { + it('limits cache size by removing a random item', () => { + const cache = new CacheObject({cacheSize: 5}); + const entries = [1, 2, 3, 4, 5, 6]; + const get = cache.get.bind(cache); + fillCacheWith(cache, entries); + expect(entries.every(get)).toBe(false); + }); + + it('shrinks when removing existing items manually', () => { + const cache = new CacheObject({cacheSize: 5}); + const entries = [1, 2, 3, 4, 5]; + const get = cache.get.bind(cache); + fillCacheWith(cache, entries); + expect(entries.every(get)).toBe(true); + cache.remove('non-existant'); + cache.remove(5); + expect(cache.get(5)).toBeUndefined(); + cache.set(5, 5); + expect(entries.every(get)).toBe(true); + cache.set(6, 6); + expect(entries.every(get)).toBe(false); + }); + }); +} + +export default testRrBehavior; diff --git a/src/index.d.ts b/src/index.d.ts index 3db31647..c417aeb6 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -4327,6 +4327,15 @@ export class LruObjectCache implements ICacheObject { isValidCacheKey(key: ObjectCacheKey): boolean; } +export class RrObjectCache implements ICacheObject { + constructor(options: {cacheSize: number}); + set(key: ObjectCacheKey, selectorFn: any): void; + get(key: ObjectCacheKey): any; + remove(key: ObjectCacheKey): void; + clear(): void; + isValidCacheKey(key: ObjectCacheKey): boolean; +} + export class FlatMapCache implements ICacheObject { set(key: any, selectorFn: any): void; get(key: any): any; @@ -4350,6 +4359,14 @@ export class LruMapCache implements ICacheObject { clear(): void; } +export class RrMapCache implements ICacheObject { + constructor(options: {cacheSize: number}); + set(key: any, selectorFn: any): void; + get(key: any): any; + remove(key: any): void; + clear(): void; +} + /* * Key selector creators */ diff --git a/src/index.js b/src/index.js index f32b037d..c0f19317 100644 --- a/src/index.js +++ b/src/index.js @@ -11,3 +11,5 @@ export {default as LruObjectCache} from './cache/LruObjectCache'; export {default as FlatMapCache} from './cache/FlatMapCache'; export {default as FifoMapCache} from './cache/FifoMapCache'; export {default as LruMapCache} from './cache/LruMapCache'; +export {default as RrObjectCache} from './cache/RrObjectCache'; +export {default as RrMapCache} from './cache/RrMapCache'; From 2d7ae225e8b4be9528e36d094695de65f6c27b2f Mon Sep 17 00:00:00 2001 From: Wes Roberts Date: Tue, 9 Jun 2020 20:34:12 -0400 Subject: [PATCH 2/5] Updated snapshot --- .../bundles-snapshot.test.js.snap | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/jest/__snapshots__/bundles-snapshot.test.js.snap b/jest/__snapshots__/bundles-snapshot.test.js.snap index d3d2b40f..b8248e1a 100644 --- a/jest/__snapshots__/bundles-snapshot.test.js.snap +++ b/jest/__snapshots__/bundles-snapshot.test.js.snap @@ -376,9 +376,7 @@ exports[`Dist bundle is unchanged 1`] = ` cacheSize = _ref.cacheSize; validateCacheSize(cacheSize); - this._cache = {}; - this._cacheKeys = []; - this._cacheLength = 0; + this.clear(); this._cacheSize = cacheSize; } @@ -404,10 +402,8 @@ exports[`Dist bundle is unchanged 1`] = ` if (index > -1) { delete this._cache[key]; - var lastIndex = this._cacheLength - 1; - var lastKey = this._cacheKeys[lastIndex]; - this._cacheKeys[index] = lastKey; this._cacheLength--; + this._cacheKeys[index] = this._cacheKeys[this._cacheLength]; } }; @@ -419,8 +415,7 @@ exports[`Dist bundle is unchanged 1`] = ` _proto._randomReplace = function _randomReplace(newKey, newValue) { var index = Math.floor(Math.random() * this._cacheLength); - var key = this._cacheKeys[index]; - delete this._cache[key]; + delete this._cache[this._cacheKeys[index]]; this._cacheKeys[index] = newKey; this._cache[newKey] = newValue; }; @@ -460,14 +455,13 @@ exports[`Dist bundle is unchanged 1`] = ` }; _proto.remove = function remove(key) { - var index = this._cacheKeys.indexOf(key); + var index = this._cacheKeys.indexOf(key); // O(1) + if (index > -1) { delete this._cache[\\"delete\\"](key); - var lastIndex = this._cacheLength - 1; - var lastKey = this._cacheKeys[lastIndex]; - this._cacheKeys[index] = lastKey; this._cacheLength--; + this._cacheKeys[index] = this._cacheKeys[this._cacheLength]; } }; @@ -479,9 +473,8 @@ exports[`Dist bundle is unchanged 1`] = ` _proto._randomReplace = function _randomReplace(newKey, newValue) { var index = Math.floor(Math.random() * this._cacheLength); - var key = this._cacheKeys[index]; - this._cache[\\"delete\\"](key); + this._cache[\\"delete\\"](this._cacheKeys[index]); this._cacheKeys[index] = newKey; From 80c37d1b13c4e68e06aeca798ed5cc386fea0fac Mon Sep 17 00:00:00 2001 From: Wes Roberts Date: Fri, 3 Nov 2023 03:58:16 -0400 Subject: [PATCH 3/5] RrObjectCache removed --- .../bundles-snapshot.test.js.snap | 69 ++----------------- src/cache/README.md | 1 - src/cache/RrMapCache.js | 12 ++-- src/cache/RrObjectCache.js | 44 ------------ src/cache/__tests__/RrObjectCache.spec.js | 12 ---- src/index.d.ts | 9 --- src/index.js | 1 - 7 files changed, 8 insertions(+), 140 deletions(-) delete mode 100644 src/cache/RrObjectCache.js delete mode 100644 src/cache/__tests__/RrObjectCache.spec.js diff --git a/jest/__snapshots__/bundles-snapshot.test.js.snap b/jest/__snapshots__/bundles-snapshot.test.js.snap index b8248e1a..82cd60af 100644 --- a/jest/__snapshots__/bundles-snapshot.test.js.snap +++ b/jest/__snapshots__/bundles-snapshot.test.js.snap @@ -370,63 +370,6 @@ exports[`Dist bundle is unchanged 1`] = ` return LruMapCache; }(); - var RrObjectCache = /*#__PURE__*/function () { - function RrObjectCache(_temp) { - var _ref = _temp === void 0 ? {} : _temp, - cacheSize = _ref.cacheSize; - - validateCacheSize(cacheSize); - this.clear(); - this._cacheSize = cacheSize; - } - - var _proto = RrObjectCache.prototype; - - _proto.set = function set(key, selectorFn) { - if (this._cacheLength >= this._cacheSize) { - this._randomReplace(key, selectorFn); - } else { - this._cache[key] = selectorFn; - this._cacheKeys[this._cacheLength] = key; - this._cacheLength++; - } - }; - - _proto.get = function get(key) { - return this._cache[key]; - }; - - _proto.remove = function remove(key) { - var index = this._cacheKeys.indexOf(key); // O(1) - - - if (index > -1) { - delete this._cache[key]; - this._cacheLength--; - this._cacheKeys[index] = this._cacheKeys[this._cacheLength]; - } - }; - - _proto.clear = function clear() { - this._cache = {}; - this._cacheKeys = []; - this._cacheLength = 0; - }; - - _proto._randomReplace = function _randomReplace(newKey, newValue) { - var index = Math.floor(Math.random() * this._cacheLength); - delete this._cache[this._cacheKeys[index]]; - this._cacheKeys[index] = newKey; - this._cache[newKey] = newValue; - }; - - _proto.isValidCacheKey = function isValidCacheKey(cacheKey) { - return isStringOrNumber(cacheKey); - }; - - return RrObjectCache; - }(); - var RrMapCache = /*#__PURE__*/function () { function RrMapCache(_temp) { var _ref = _temp === void 0 ? {} : _temp, @@ -440,13 +383,12 @@ exports[`Dist bundle is unchanged 1`] = ` var _proto = RrMapCache.prototype; _proto.set = function set(key, selectorFn) { - if (this._cacheLength >= this._cacheSize) { + if (this._cache.size >= this._cacheSize) { this._randomReplace(key, selectorFn); } else { this._cache.set(key, selectorFn); - this._cacheKeys[this._cacheLength] = key; - this._cacheLength++; + this._cacheKeys[this._cache.size] = key; } }; @@ -460,19 +402,17 @@ exports[`Dist bundle is unchanged 1`] = ` if (index > -1) { delete this._cache[\\"delete\\"](key); - this._cacheLength--; - this._cacheKeys[index] = this._cacheKeys[this._cacheLength]; + this._cacheKeys[index] = this._cacheKeys[this._cache.size]; } }; _proto.clear = function clear() { this._cache = new Map(); this._cacheKeys = []; - this._cacheLength = 0; }; _proto._randomReplace = function _randomReplace(newKey, newValue) { - var index = Math.floor(Math.random() * this._cacheLength); + var index = Math.floor(Math.random() * this._cache.size); this._cache[\\"delete\\"](this._cacheKeys[index]); @@ -491,7 +431,6 @@ exports[`Dist bundle is unchanged 1`] = ` exports.LruMapCache = LruMapCache; exports.LruObjectCache = LruObjectCache; exports.RrMapCache = RrMapCache; - exports.RrObjectCache = RrObjectCache; exports.createCachedSelector = createCachedSelector; exports.createStructuredCachedSelector = createStructuredCachedSelector; exports[\\"default\\"] = createCachedSelector; diff --git a/src/cache/README.md b/src/cache/README.md index 014f8660..91ce7264 100644 --- a/src/cache/README.md +++ b/src/cache/README.md @@ -11,7 +11,6 @@ | [`FlatObjectCache`](./FlatObjectCache.js) | `number` `string` | flat unlimited | JS object | | [`FifoObjectCache`](./FifoObjectCache.js) | `number` `string` | [first in first out][docs-fifo-cache] | JS object | | [`LruObjectCache`](./LruObjectCache.js) | `number` `string` | [least recently used][docs-lru-cache] | JS object | -| [`RrObjectCache`](./RrObjectCache.js) | `number` `string` | [random replacement][docs-rr-cache] | JS object | | [`FlatMapCache`](./FlatMapCache.js) | any | flat unlimited | [Map object][docs-mozilla-map] | | [`FifoMapCache`](./FifoMapCache.js) | any | [first in first out][docs-fifo-cache] | [Map object][docs-mozilla-map] | | [`LruMapCache`](./LruMapCache.js) | any | [least recently used][docs-lru-cache] | [Map object][docs-mozilla-map] | diff --git a/src/cache/RrMapCache.js b/src/cache/RrMapCache.js index cde4ad65..26fd685f 100644 --- a/src/cache/RrMapCache.js +++ b/src/cache/RrMapCache.js @@ -1,5 +1,4 @@ import validateCacheSize from './util/validateCacheSize'; -import isStringOrNumber from './util/isStringOrNumber'; export default class RrMapCache { constructor({cacheSize} = {}) { @@ -8,12 +7,11 @@ export default class RrMapCache { this._cacheSize = cacheSize; } set(key, selectorFn) { - if (this._cacheLength >= this._cacheSize) { + if (this._cache.size >= this._cacheSize) { this._randomReplace(key, selectorFn); } else { this._cache.set(key, selectorFn); - this._cacheKeys[this._cacheLength] = key; - this._cacheLength++; + this._cacheKeys[this._cache.size] = key; } } get(key) { @@ -23,17 +21,15 @@ export default class RrMapCache { const index = this._cacheKeys.indexOf(key); // O(1) if (index > -1) { delete this._cache.delete(key); - this._cacheLength--; - this._cacheKeys[index] = this._cacheKeys[this._cacheLength]; + this._cacheKeys[index] = this._cacheKeys[this._cache.size]; } } clear() { this._cache = new Map(); this._cacheKeys = []; - this._cacheLength = 0; } _randomReplace(newKey, newValue) { - const index = Math.floor(Math.random() * this._cacheLength); + const index = Math.floor(Math.random() * this._cache.size); this._cache.delete(this._cacheKeys[index]); this._cacheKeys[index] = newKey; this._cache.set(newKey, newValue); diff --git a/src/cache/RrObjectCache.js b/src/cache/RrObjectCache.js deleted file mode 100644 index 6440ed48..00000000 --- a/src/cache/RrObjectCache.js +++ /dev/null @@ -1,44 +0,0 @@ -import validateCacheSize from './util/validateCacheSize'; -import isStringOrNumber from './util/isStringOrNumber'; - -export default class RrObjectCache { - constructor({cacheSize} = {}) { - validateCacheSize(cacheSize); - this.clear(); - this._cacheSize = cacheSize; - } - set(key, selectorFn) { - if (this._cacheLength >= this._cacheSize) { - this._randomReplace(key, selectorFn); - } else { - this._cache[key] = selectorFn; - this._cacheKeys[this._cacheLength] = key; - this._cacheLength++; - } - } - get(key) { - return this._cache[key]; - } - remove(key) { - const index = this._cacheKeys.indexOf(key); // O(1) - if (index > -1) { - delete this._cache[key]; - this._cacheLength--; - this._cacheKeys[index] = this._cacheKeys[this._cacheLength]; - } - } - clear() { - this._cache = {}; - this._cacheKeys = []; - this._cacheLength = 0; - } - _randomReplace(newKey, newValue) { - const index = Math.floor(Math.random() * this._cacheLength); - delete this._cache[this._cacheKeys[index]]; - this._cacheKeys[index] = newKey; - this._cache[newKey] = newValue; - } - isValidCacheKey(cacheKey) { - return isStringOrNumber(cacheKey); - } -} diff --git a/src/cache/__tests__/RrObjectCache.spec.js b/src/cache/__tests__/RrObjectCache.spec.js deleted file mode 100644 index 4d69bf55..00000000 --- a/src/cache/__tests__/RrObjectCache.spec.js +++ /dev/null @@ -1,12 +0,0 @@ -import {RrObjectCache as CacheObject} from '../../../src/index'; -import testBasicBehavior from '../__util__/testBasicBehavior'; -import testRrBehavior from '../__util__/testRrBehavior'; -import testCacheSizeOptionValidation from '../__util__/testCacheSizeOptionValidation'; -import testObjectCacheKeyBehavior from '../__util__/testObjectCacheKeyBehavior'; - -describe('RrObjectCache', () => { - testBasicBehavior(CacheObject, {cacheSize: 10}); - testRrBehavior(CacheObject); - testCacheSizeOptionValidation(CacheObject); - testObjectCacheKeyBehavior(CacheObject, {cacheSize: 10}); -}); diff --git a/src/index.d.ts b/src/index.d.ts index c417aeb6..749886cf 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -4327,15 +4327,6 @@ export class LruObjectCache implements ICacheObject { isValidCacheKey(key: ObjectCacheKey): boolean; } -export class RrObjectCache implements ICacheObject { - constructor(options: {cacheSize: number}); - set(key: ObjectCacheKey, selectorFn: any): void; - get(key: ObjectCacheKey): any; - remove(key: ObjectCacheKey): void; - clear(): void; - isValidCacheKey(key: ObjectCacheKey): boolean; -} - export class FlatMapCache implements ICacheObject { set(key: any, selectorFn: any): void; get(key: any): any; diff --git a/src/index.js b/src/index.js index c0f19317..4830a675 100644 --- a/src/index.js +++ b/src/index.js @@ -11,5 +11,4 @@ export {default as LruObjectCache} from './cache/LruObjectCache'; export {default as FlatMapCache} from './cache/FlatMapCache'; export {default as FifoMapCache} from './cache/FifoMapCache'; export {default as LruMapCache} from './cache/LruMapCache'; -export {default as RrObjectCache} from './cache/RrObjectCache'; export {default as RrMapCache} from './cache/RrMapCache'; From b35f2db8e594946a3661a2f75d37142b425b3d16 Mon Sep 17 00:00:00 2001 From: Wes Roberts Date: Fri, 3 Nov 2023 04:02:48 -0400 Subject: [PATCH 4/5] src/cache/README.md: several vs 7 wording --- src/cache/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cache/README.md b/src/cache/README.md index 91ce7264..fc3e49e4 100644 --- a/src/cache/README.md +++ b/src/cache/README.md @@ -4,7 +4,7 @@ ## Available cache objects -`re-reselect` ships with several **ready-to-use cache object constructors**: +`re-reselect` ships with **7 ready-to-use cache object constructors**: | name | accepted cacheKey | type | storage | | :---------------------------------------: | :---------------: | :-----------------------------------: | :----------------------------: | From 055c0b26d012114f0f28701c259814aaad46b54f Mon Sep 17 00:00:00 2001 From: Wes Roberts Date: Tue, 14 Nov 2023 20:20:39 -0500 Subject: [PATCH 5/5] RrMapCache 0 index bug fix --- src/cache/RrMapCache.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cache/RrMapCache.js b/src/cache/RrMapCache.js index 26fd685f..6993eb27 100644 --- a/src/cache/RrMapCache.js +++ b/src/cache/RrMapCache.js @@ -10,8 +10,8 @@ export default class RrMapCache { if (this._cache.size >= this._cacheSize) { this._randomReplace(key, selectorFn); } else { - this._cache.set(key, selectorFn); this._cacheKeys[this._cache.size] = key; + this._cache.set(key, selectorFn); } } get(key) {