mirror of
https://github.com/public-transport/db-vendo-client.git
synced 2025-02-23 07:09:35 +02:00
improve findInTree performance
by passing a list of paths to find in the tree up front #154 closes #152
This commit is contained in:
parent
940519b15b
commit
8cb7d807f2
2 changed files with 45 additions and 41 deletions
|
@ -1,19 +1,20 @@
|
|||
'use strict'
|
||||
'use strict';
|
||||
|
||||
const scanner = require('object-scan')
|
||||
const objectScan = require('object-scan');
|
||||
|
||||
// For all items in `tree` matching a path selector specified
|
||||
// in `selector`, call `onResult` with the item, its parent and
|
||||
// the path to the item.
|
||||
// Example:
|
||||
// tree: {foo: [{bar: 1}], hey: {there: [{bar: 2}]}}
|
||||
// selector: **[*].bar
|
||||
const findInTree = (tree, selector, onResult) => {
|
||||
scanner([selector], {
|
||||
filterFn: (key, value, { parents }) => {
|
||||
onResult(value, parents[0], key);
|
||||
const findInTree = (haystack, needles) => {
|
||||
const result = Object.create(null);
|
||||
needles.forEach((needle) => {
|
||||
result[needle] = [];
|
||||
});
|
||||
objectScan(needles, {
|
||||
filterFn: (key, value, { parents, matchedBy }) => {
|
||||
matchedBy.forEach((needle) => {
|
||||
result[needle].push([value, parents]);
|
||||
});
|
||||
}
|
||||
})(tree);
|
||||
}
|
||||
})(haystack);
|
||||
return result;
|
||||
};
|
||||
|
||||
module.exports = findInTree
|
||||
module.exports = findInTree;
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
'use strict'
|
||||
|
||||
const get = require('lodash/get')
|
||||
const findInTree = require('../lib/find-in-tree')
|
||||
|
||||
const parseCommonData = (_ctx) => {
|
||||
const {profile, opt, res} = _ctx
|
||||
const c = res.common || {}
|
||||
const matches = findInTree(res, [
|
||||
'**.oprX', '**.icoX', '**.prodX', '**.pRefL', '**.locX',
|
||||
'**.ani.fLocX', '**.ani.tLocX', '**.fLocX', '**.tLocX',
|
||||
'**.remX', '**.himX', '**.polyG.polyXL'
|
||||
]);
|
||||
|
||||
const common = {}
|
||||
const ctx = {..._ctx, common}
|
||||
|
@ -13,16 +17,16 @@ const parseCommonData = (_ctx) => {
|
|||
common.operators = []
|
||||
if (Array.isArray(c.opL)) {
|
||||
common.operators = c.opL.map(op => profile.parseOperator(ctx, op))
|
||||
findInTree(res, '**.oprX', (idx, parent) => {
|
||||
if ('number' === typeof idx) parent.operator = common.operators[idx]
|
||||
matches['**.oprX'].forEach(([idx, parents]) => {
|
||||
if ('number' === typeof idx) parents[0].operator = common.operators[idx]
|
||||
})
|
||||
}
|
||||
|
||||
common.icons = []
|
||||
if (Array.isArray(c.icoL)) {
|
||||
common.icons = c.icoL.map(icon => profile.parseIcon(ctx, icon))
|
||||
findInTree(res, '**.icoX', (idx, parent) => {
|
||||
if ('number' === typeof idx) parent.icon = common.icons[idx]
|
||||
matches['**.icoX'].forEach(([idx, parents]) => {
|
||||
if ('number' === typeof idx) parents[0].icon = common.icons[idx]
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -30,11 +34,11 @@ const parseCommonData = (_ctx) => {
|
|||
if (Array.isArray(c.prodL)) {
|
||||
common.lines = c.prodL.map(l => profile.parseLine(ctx, l))
|
||||
|
||||
findInTree(res, '**.prodX', (idx, parent) => {
|
||||
if ('number' === typeof idx) parent.line = common.lines[idx]
|
||||
matches['**.prodX'].forEach(([idx, parents]) => {
|
||||
if ('number' === typeof idx) parents[0].line = common.lines[idx]
|
||||
})
|
||||
findInTree(res, '**.pRefL', (idxs, parent) => {
|
||||
parent.lines = idxs.filter(idx => !!common.lines[idx]).map(idx => common.lines[idx])
|
||||
matches['**.pRefL'].forEach(([idxs, parents]) => {
|
||||
parents[0].lines = idxs.filter(idx => !!common.lines[idx]).map(idx => common.lines[idx])
|
||||
})
|
||||
// todo
|
||||
// **.dep.dProdX: departureLine -> common.lines[idx]
|
||||
|
@ -55,35 +59,35 @@ const parseCommonData = (_ctx) => {
|
|||
}
|
||||
|
||||
// todo: correct props?
|
||||
findInTree(res, '**.locX', (idx, parent) => {
|
||||
if ('number' === typeof idx) parent.location = common.locations[idx]
|
||||
matches['**.locX'].forEach(([idx, parents]) => {
|
||||
if ('number' === typeof idx) parents[0].location = common.locations[idx]
|
||||
})
|
||||
findInTree(res, '**.ani.fLocX', (idxs, parent) => {
|
||||
parent.fromLocations = idxs.map(idx => common.locations[idx])
|
||||
matches['**.ani.fLocX'].forEach(([idxs, parents]) => {
|
||||
parents[0].fromLocations = idxs.map(idx => common.locations[idx])
|
||||
})
|
||||
findInTree(res, '**.ani.tLocX', (idxs, parent) => {
|
||||
parent.toLocations = idxs.map(idx => common.locations[idx])
|
||||
matches['**.ani.tLocX'].forEach(([idxs, parents]) => {
|
||||
parents[0].toLocations = idxs.map(idx => common.locations[idx])
|
||||
})
|
||||
findInTree(res, '**.fLocX', (idx, parent) => {
|
||||
if ('number' === typeof idx) parent.fromLocation = common.locations[idx]
|
||||
matches['**.fLocX'].forEach(([idx, parents]) => {
|
||||
if ('number' === typeof idx) parents[0].fromLocation = common.locations[idx]
|
||||
})
|
||||
findInTree(res, '**.tLocX', (idx, parent) => {
|
||||
if ('number' === typeof idx) parent.toLocation = common.locations[idx]
|
||||
matches['**.tLocX'].forEach(([idx, parents]) => {
|
||||
if ('number' === typeof idx) parents[0].toLocation = common.locations[idx]
|
||||
})
|
||||
}
|
||||
|
||||
common.hints = []
|
||||
if (opt.remarks && Array.isArray(c.remL)) {
|
||||
common.hints = c.remL.map(hint => profile.parseHint(ctx, hint))
|
||||
findInTree(res, '**.remX', (idx, parent) => {
|
||||
if ('number' === typeof idx) parent.hint = common.hints[idx]
|
||||
matches['**.remX'].forEach(([idx, parents]) => {
|
||||
if ('number' === typeof idx) parents[0].hint = common.hints[idx]
|
||||
})
|
||||
}
|
||||
common.warnings = []
|
||||
if (opt.remarks && Array.isArray(c.himL)) {
|
||||
common.warnings = c.himL.map(w => profile.parseWarning(ctx, w))
|
||||
findInTree(res, '**.himX', (idx, parent) => {
|
||||
if ('number' === typeof idx) parent.warning = common.warnings[idx]
|
||||
matches['**.himX'].forEach(([idx, parents]) => {
|
||||
if ('number' === typeof idx) parents[0].warning = common.warnings[idx]
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -92,10 +96,9 @@ const parseCommonData = (_ctx) => {
|
|||
common.polylines = c.polyL.map(p => profile.parsePolyline(ctx, p))
|
||||
// todo: **.ani.poly -> parsePolyline()
|
||||
|
||||
findInTree(res, '**.polyG.polyXL', (idxs, _, path) => {
|
||||
matches['**.polyG.polyXL'].forEach(([idxs, parents]) => {
|
||||
const idx = idxs.find(idx => !!common.polylines[idx]) // find any given polyline
|
||||
const jny = get(res, path.slice(0, -2))
|
||||
jny.polyline = common.polylines[idx]
|
||||
parents[1].polyline = common.polylines[idx]
|
||||
})
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue