@apollo/query-planner
Version:
Apollo Query Planner
97 lines • 3.42 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateAllPlansAndFindBest = void 0;
const federation_internals_1 = require("@apollo/federation-internals");
function generateAllPlansAndFindBest({ initial, toAdd, addFct, costFct, onPlan = () => { }, }) {
const stack = [{
partial: initial,
remaining: toAdd,
isRoot: true,
index: 0,
}];
let min = undefined;
while (stack.length > 0) {
const { partial, partialCost, remaining, isRoot, index } = stack.pop();
if (min !== undefined && partialCost !== undefined && partialCost >= min.cost) {
continue;
}
const nextChoices = remaining[0];
const otherChoices = remaining.slice(1);
const pickedIndex = pickNext(index, nextChoices);
const { extracted, updatedChoices, isLast } = extract(pickedIndex, nextChoices);
if (!isLast) {
insertInStack({
partial,
remaining: [updatedChoices].concat(otherChoices),
isRoot,
index: isRoot && index !== undefined && index < nextChoices.length - 1 ? index + 1 : undefined,
partialCost,
}, stack);
}
const newPartial = addFct(partial, extracted);
const cost = costFct(newPartial);
if (otherChoices.length === 0) {
const isNewMin = min === undefined || cost < min.cost;
onPlan(newPartial, cost, min === null || min === void 0 ? void 0 : min.cost);
if (isNewMin) {
min = {
best: newPartial,
cost
};
}
continue;
}
if (min === undefined || cost < min.cost) {
insertInStack({
partial: newPartial,
partialCost: cost,
remaining: otherChoices,
isRoot: false,
index,
}, stack);
}
}
(0, federation_internals_1.assert)(min, 'A plan should have been found');
return min;
}
exports.generateAllPlansAndFindBest = generateAllPlansAndFindBest;
function insertInStack(elt, stack) {
if (elt.index !== undefined) {
stack.push(elt);
}
else {
stack.unshift(elt);
}
}
function pickNext(index, remaining) {
if (index === undefined || index >= remaining.length) {
for (let i = 0; i < remaining.length; i++) {
if (remaining[i] !== undefined) {
return i;
}
}
(0, federation_internals_1.assert)(false, 'Passed a "remaining" with all undefined');
}
else {
(0, federation_internals_1.assert)(remaining[index] !== undefined, () => `Invalid index ${index}`);
return index;
}
}
function extract(index, choices) {
const extracted = choices[index];
(0, federation_internals_1.assert)(extracted !== undefined, () => `Index ${index} of ${choices} is undefined`);
const updatedChoices = new Array(choices.length);
let isLast = true;
for (let i = 0; i < choices.length; i++) {
if (i !== index) {
isLast && (isLast = choices[i] === undefined);
updatedChoices[i] = choices[i];
}
}
return {
extracted,
isLast,
updatedChoices,
};
}
//# sourceMappingURL=generateAllPlans.js.map
;