feat: improved SimpleDataStore.hold() again

this time uses an internal Set()

this should hopefully be the final iteration of this helper class until
a new "strategy" needs to be added
This commit is contained in:
Bobby 2022-07-06 17:49:13 +07:00
parent 17c863f724
commit b9d0f787d7
No known key found for this signature in database
GPG Key ID: 941839794CBF5A09

View File

@ -5,7 +5,7 @@ const STRATEGIES = [
class SimpleDataStore { class SimpleDataStore {
#store #store
#size #held
#limit #limit
#strategy #strategy
@ -23,36 +23,35 @@ class SimpleDataStore {
} }
this.#store = new Map() this.#store = new Map()
this.#size = this.#store.size this.#held = new Set()
this.#limit = options.limit this.#limit = options.limit
this.#strategy = options.strategy this.#strategy = options.strategy
} }
clear () { clear () {
this.#store.clear() this.#store.clear()
this.#size = 0 this.#held.clear()
} }
delete (key) { delete (key) {
if (this.#store.delete(key)) { // If key is in #held, assume is not in #store, thus return early
this.#size-- return this.#held.delete(key) || this.#store.delete(key)
return true
}
return false
} }
deleteStalest () { deleteStalest () {
const stalest = this.getStalest() const stalest = this.getStalest()
if (stalest) { if (stalest) {
return this.delete(stalest) return this.#store.delete(stalest)
} }
} }
get (key) { get (key) {
// null should be used as an indicator for when key is held but not yet set with value
if (this.#held.has(key)) {
return null
}
const entry = this.#store.get(key) const entry = this.#store.get(key)
// This may return undefined or null
// undefined should be an indicator for when the key legitimately has not been set,
// null should be an indicator for when the key is still being held via hold() function
if (!entry) return entry if (!entry) return entry
switch (this.#strategy) { switch (this.#strategy) {
@ -76,7 +75,7 @@ class SimpleDataStore {
case STRATEGIES[0]: case STRATEGIES[0]:
case STRATEGIES[1]: case STRATEGIES[1]:
for (const entry of this.#store) { for (const entry of this.#store) {
if (entry[1] && entry[1].stratval < stalest[1].stratval) { if (entry[1].stratval < stalest[1].stratval) {
stalest = entry stalest = entry
} }
} }
@ -88,12 +87,11 @@ class SimpleDataStore {
} }
hold (key) { hold (key) {
this.#store.set(key, null) return this.#held.add(key) && true
return true
} }
set (key, value) { set (key, value) {
if (this.#size >= this.#limit) { if (!this.#store.has(key) && this.#store.size >= this.#limit) {
this.deleteStalest() this.deleteStalest()
} }
@ -108,7 +106,7 @@ class SimpleDataStore {
} }
if (this.#store.set(key, { value, stratval })) { if (this.#store.set(key, { value, stratval })) {
this.#size++ this.#held.delete(key)
return true return true
} }
return false return false
@ -123,7 +121,7 @@ class SimpleDataStore {
} }
get size () { get size () {
return this.#size return this.#store.size
} }
set size (_) { set size (_) {
@ -138,10 +136,18 @@ class SimpleDataStore {
throw Error('This property is read-only.') throw Error('This property is read-only.')
} }
// Not advised to use the following functions during production
// Mainly intended to "inspect" internal stores when required
get store () { get store () {
// return shallow copy // return shallow copy
return new Map(this.#store) return new Map(this.#store)
} }
get held () {
// return shallow copy
return new Set(this.#held)
}
} }
module.exports = SimpleDataStore module.exports = SimpleDataStore