UNPKG

@casual-simulation/aux-common

Version:
78 lines 2.66 kB
import { calculateBotValue } from './BotCalculations'; import { zip, sortBy } from 'es-toolkit/compat'; /** * Creates a lookup table for the given tags. * This makes repeated queries against the same tags much quicker. * @param calc The calculation context. * @param tags The tags that the lookup table should be built from. * @param defaults The default values that should be used for tags that are missing. */ export function buildLookupTable(calc, tags, defaults = null) { return new BotLookupTable(calc, tags, defaults); } /** * Defines a lookup table for a group of bots. * Lookup tables help performance by calculating lists of bots which have the same values for * a given set of tags. This makes subsequent queries for the same set of tags effectively a O(1) operation instead of a O(N) operation. * * Building the table is O(N) because all the bots need to be scanned to build the table. */ export class BotLookupTable { constructor(calc, tags, defaults) { this._map = new Map(); this._tags = sortBy(tags); for (let bot of calc.objects) { const val = calculateTagValueKey(calc, bot, tags, defaults); if (val !== null) { this._saveBot(val, bot); } } } /** * Queries the lookup table. * @param values The values to query. */ query(values) { return this._map.get(valuesToKey(values)) || []; } toString() { return `BotLookupTable[${this._tags.join(',')}]`; } _saveBot(key, bot) { let list = this._map.get(key); if (!list) { list = []; this._map.set(key, list); } list.push(bot); } } /** * Calculates a key from the given bot's tags that can be used for the lookup table. * If null is returned then the key should not be used. (i.e. the bot should not be stored in the table) * @param calc The bot calculation context. * @param bot The bot. * @param tags The tags. * @param defaults The default values to use if any of the tags are missing. */ function calculateTagValueKey(calc, bot, tags, defaults) { let values = []; if (!defaults) { defaults = new Array(tags.length); } for (let [tag, def] of zip(tags, defaults)) { let val = calculateBotValue(calc, bot, tag); if (typeof val === 'undefined') { val = def; } if (typeof val === 'undefined') { return null; } values.push(val); } return valuesToKey(values); } export function valuesToKey(values) { return values.join(':'); } //# sourceMappingURL=BotLookupTable.js.map