Skip to content

Commit

Permalink
Add caching to @Guid resolution. Closes #21
Browse files Browse the repository at this point in the history
  • Loading branch information
brollb committed Apr 4, 2022
1 parent a25c6ae commit a95682e
Showing 1 changed file with 60 additions and 5 deletions.
65 changes: 60 additions & 5 deletions src/common/JSONImporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ define([
return resolved;
}

return await selector.findNode(this.core, this.rootNode, parent);
return await selector.findNode(this.core, this.rootNode, parent, resolvedSelectors.cache);
}

async getNode(parent, idString, resolvedSelectors) {
Expand Down Expand Up @@ -727,7 +727,7 @@ define([
}
}

async findNode(core, rootNode, parent) {
async findNode(core, rootNode, parent, nodeCache) {
if (this.tag === '@path') {
return await core.loadByPath(rootNode, this.value);
}
Expand Down Expand Up @@ -771,16 +771,37 @@ define([
}

if (this.tag === '@guid') {
return await this.findNodeWhere(
const getCacheKey = node => new NodeSelector(`@guid:${core.getGuid(node)}`);
return await this.cachedSearch(
core,
rootNode,
node => core.getGuid(node) === this.value
node => core.getGuid(node) === this.value,
getCacheKey,
nodeCache
);
}

throw new Error(`Unknown tag: ${this.tag}`);
}

async cachedSearch(core, node, fn, cacheKey, nodeCache) {
return await this.findNodeWhere(
core,
node,
node => {
if (fn(node)) {
return true;
} else {
const key = cacheKey(node);
const parent = core.getParent(node);
if (parent) {
nodeCache.record(core.getPath(parent), key, node);
}
}
},
);
}

async findNodeWhere(core, node, fn) {
if (await fn(node)) {
return node;
Expand All @@ -807,8 +828,11 @@ define([
}

class NodeSelections {
constructor() {
constructor(withCache=true) {
this.selections = {};
if (withCache) {
this.cache = new NodeCache(500);
}
}

getAbsoluteTag(parentId, selector) {
Expand All @@ -825,10 +849,41 @@ define([
}

get(parentId, selector) {
const cachedValue = this.cache?.get(parentId, selector);
if (cachedValue) return cachedValue;
return this.selections[this.getAbsoluteTag(parentId, selector)];
}
}

class NodeCache extends NodeSelections {
constructor(maxSize) {
super(false);
this.maxSize = maxSize;
this.length = 0;
}

record(parentId, selector, node) {
if (this.length < this.maxSize) {
super.record(parentId, selector, node);
this.length++;
}
}

get(parentId, selector) {
const value = super.get(parentId, selector);
if (value) {
this.remove(parentId, selector);
}
return value;
}

remove(parentId, selector) {
const absTag = this.getAbsoluteTag(parentId, selector);
delete this.selections[absTag];
this.length--;
}
}

Importer.NodeSelector = NodeSelector;
return Importer;
});

0 comments on commit a95682e

Please sign in to comment.