diff options
author | (quasar) nebula <qznebula@protonmail.com> | 2024-01-17 14:15:24 -0400 |
---|---|---|
committer | (quasar) nebula <qznebula@protonmail.com> | 2024-01-17 16:09:59 -0400 |
commit | ebe2a4d41c55be1250d4964ab16b788f70d5943b (patch) | |
tree | 6dbf9ee10b0a0ff955c7f3d9be9c608c9a3bc394 /src/data | |
parent | 61e675cd51946c5cc2bbdd500df620e0c870bd3d (diff) |
data: withReverseContributionList: cache all results per data array
Diffstat (limited to 'src/data')
-rw-r--r-- | src/data/composite/wiki-data/withReverseContributionList.js | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/src/data/composite/wiki-data/withReverseContributionList.js b/src/data/composite/wiki-data/withReverseContributionList.js index 71e3c1a8..7b07e24a 100644 --- a/src/data/composite/wiki-data/withReverseContributionList.js +++ b/src/data/composite/wiki-data/withReverseContributionList.js @@ -4,6 +4,10 @@ // up subsequent similar accesses. Reverse contribution lists are the most // costly in live-dev-server, but we intend to expand the impelemntation here // to reverse reference lists in general later on. +// +// This has absolutely not been rigorously tested with altering properties of +// data objects in a wiki data array which is reused. If a new wiki data array +// is used, a fresh cache will always be created. import {input, templateCompositeFrom} from '#composite'; @@ -11,6 +15,12 @@ import {exitWithoutDependency} from '#composite/control-flow'; import inputWikiData from './inputWikiData.js'; +// Mapping of reference list property to WeakMap. +// Each WeakMap maps a wiki data array to another weak map, +// which in turn maps each referenced thing to an array of +// things referencing it. +const caches = new Map(); + export default templateCompositeFrom({ annotation: `withReverseContributionList`, @@ -35,11 +45,35 @@ export default templateCompositeFrom({ [input.myself()]: myself, [input('data')]: data, [input('list')]: list, - }) => - continuation({ + }) => { + if (!caches.has(list)) { + caches.set(list, new WeakMap()); + } + + const cache = caches.get(list); + + if (!cache.has(data)) { + const cacheRecord = new WeakMap(); + + for (const referencingThing of data) { + const referenceList = referencingThing[list]; + for (const {who: referencedThing} of referenceList) { + if (cacheRecord.has(referencedThing)) { + cacheRecord.get(referencedThing).push(referencingThing); + } else { + cacheRecord.set(referencedThing, [referencingThing]); + } + } + } + + cache.set(data, cacheRecord); + } + + return continuation({ ['#reverseContributionList']: - data.filter(thing => thing[list].some(({who}) => who === myself)), - }), + cache.get(data).get(myself) ?? [], + }); + }, }, ], }); |