forked from box/box-content-preview
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update: Add BoundedCache for Thumbnails Sidebar (box#917)
- Loading branch information
Conrad Chan
authored and
Conrad Chan
committed
Feb 19, 2019
1 parent
240ad38
commit 3321ff2
Showing
4 changed files
with
154 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import Cache from './Cache'; | ||
|
||
class BoundedCache extends Cache { | ||
/** @property {Array} - Maintains the list of cache keys in order in which they were added to the cache */ | ||
cacheQueue; | ||
|
||
/** @property {number} - The maximum number of entries in the cache */ | ||
maxEntries; | ||
|
||
/** | ||
* [constructor] | ||
* | ||
* @param {number} [maxEntries] - Override the maximum number of cache entries | ||
*/ | ||
constructor(maxEntries) { | ||
super(); | ||
|
||
this.maxEntries = maxEntries || 500; | ||
this.cache = {}; | ||
this.cacheQueue = []; | ||
} | ||
|
||
/** | ||
* Destroys the bounded cache | ||
* | ||
* @return {void} | ||
*/ | ||
destroy() { | ||
this.cache = null; | ||
this.cacheQueue = null; | ||
} | ||
|
||
/** | ||
* Caches a simple object in memory. If the number of cache entries | ||
* then exceeds the maxEntries value, then the earliest key in cacheQueue | ||
* will be removed from the cache. | ||
* | ||
* @param {string} key - The cache key | ||
* @param {*} value - The cache value | ||
* @return {void} | ||
*/ | ||
set(key, value) { | ||
// If this key is not already in the cache, then add it | ||
// to the cacheQueue. This avoids adding the same key to | ||
// the cacheQueue multiple times if the cache entry gets updated | ||
if (!this.inCache(key)) { | ||
this.cacheQueue.push(key); | ||
} | ||
|
||
super.set(key, value); | ||
|
||
// If the cacheQueue exceeds the maxEntries then remove the first | ||
// key from the front of the cacheQueue and unset that entry | ||
// from the cache | ||
if (this.cacheQueue.length > this.maxEntries) { | ||
const deleteKey = this.cacheQueue.shift(); | ||
this.unset(deleteKey); | ||
} | ||
} | ||
} | ||
|
||
export default BoundedCache; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
/* eslint-disable no-unused-expressions */ | ||
import BoundedCache from '../BoundedCache'; | ||
|
||
const sandbox = sinon.sandbox.create(); | ||
|
||
describe('BoundedCache', () => { | ||
let cache; | ||
|
||
beforeEach(() => { | ||
cache = new BoundedCache(2); | ||
}); | ||
|
||
afterEach(() => { | ||
sandbox.verifyAndRestore(); | ||
|
||
cache = null; | ||
}); | ||
|
||
describe('constructor()', () => { | ||
it('should initialize properties', () => { | ||
cache = new BoundedCache(); | ||
|
||
expect(cache.maxEntries).to.be.equal(500); | ||
expect(cache.cache).to.be.empty; | ||
expect(cache.cacheQueue.length).to.be.equal(0); | ||
}); | ||
|
||
it('should handle maxEntries', () => { | ||
expect(cache.maxEntries).to.be.equal(2); | ||
}); | ||
}); | ||
|
||
describe('set()', () => { | ||
it('should add the entry to the cache', () => { | ||
cache.set('foo', 'bar'); | ||
|
||
expect(cache.inCache('foo')).to.be.true; | ||
expect(cache.cacheQueue).to.be.eql(['foo']); | ||
}); | ||
|
||
it('should not update the cacheQueue if key already exists', () => { | ||
cache.set('foo', 'bar'); | ||
cache.set('foo', 'bar2'); | ||
|
||
expect(cache.inCache('foo')).to.be.true; | ||
expect(cache.get('foo')).to.be.equal('bar2'); | ||
expect(cache.cacheQueue).to.be.eql(['foo']); | ||
}); | ||
|
||
it('should remove the earliest added entry when entries exceed maxEntries', () => { | ||
cache.set('foo', 'bar'); | ||
cache.set('hello', 'world'); | ||
cache.set('goodnight', 'moon'); | ||
|
||
expect(cache.inCache('foo')).to.be.false; | ||
expect(cache.cacheQueue).to.be.eql(['hello', 'goodnight']); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters