Best results yet

This commit is contained in:
Sérgio Saquetim
2024-12-31 12:29:31 -03:00
parent 3c7963e5f6
commit 386361dcac
4 changed files with 25 additions and 13 deletions

View File

@@ -6,7 +6,6 @@ export default class DAGMap {
#nodes = new Map();
#incomingEdges = new Map();
#outgoingEdges = new Map();
#staged = new Map();
add(key, value, { before, after } = {}) {
@@ -37,25 +36,27 @@ export default class DAGMap {
}
sort() {
const firstPass = this.#topologicalSort(
let result = this.#topologicalSort(
this.#incomingEdges,
this.#outgoingEdges
);
if (this.#staged.size === 0) {
return firstPass;
return result;
}
const secondPassIncomingEdges = new Map(this.#incomingEdges.entries());
const secondPassOutgoingEdges = new Map(this.#outgoingEdges.entries());
result = result.filter((key) => !this.#staged.has(key));
Array.from(this.#staged.entries()).forEach(([key, beforeConstraints]) => {
// we need to get the leftmost node before the constraints
let leftMostNode = null;
beforeConstraints.forEach((b) => {
this.#addEdge(key, b, secondPassIncomingEdges, secondPassOutgoingEdges);
const bIndex = firstPass.indexOf(b);
const bIndex = result.indexOf(b);
if (leftMostNode === null || leftMostNode > bIndex) {
leftMostNode = bIndex - 1;
@@ -66,17 +67,17 @@ export default class DAGMap {
// "leftMostNode for",
// key,
// leftMostNode,
// firstPass[leftMostNode]
// result[leftMostNode]
// );
if (
leftMostNode !== null &&
leftMostNode >= 0 &&
!this.#staged.has(key)
!this.#staged.has(leftMostNode)
) {
// this adds an additional constraint forcing the item to be placed after the leftmost node
this.#addEdge(
firstPass[leftMostNode],
result[leftMostNode],
key,
secondPassIncomingEdges,
secondPassOutgoingEdges

View File

@@ -1,5 +1,5 @@
import DAGMap from "dag-map";
// import DAGMap from "discourse/lib/dag-map";
// import DAGMap from "dag-map";
import DAGMap from "discourse/lib/dag-map";
import { makeArray } from "discourse-common/lib/helpers";
import { bind } from "discourse-common/utils/decorators";
@@ -215,17 +215,17 @@ export default class DAG {
*/
#addHandlingCycles(dag, key, value, before, after) {
if (this.#throwErrorOnCycle) {
dag.add(key, value, before, after);
dag.add(key, value, { before, after });
} else {
try {
dag.add(key, value, before, after);
dag.add(key, value, { before, after });
} catch (e) {
if (e.message.match(/cycle/i)) {
const { before: newBefore, after: newAfter } =
this.#defaultPositionForKey(key);
// if even the default position causes a cycle, an error will be thrown
dag.add(key, value, newBefore, newAfter);
dag.add(key, value, { newBefore, newAfter });
}
}
}

View File

@@ -16,6 +16,17 @@ module("Unit | Lib | DAGMap", function (hooks) {
assert.deepEqual(sorted, ["key1", "key2", "key3"]);
});
test("Items are positioned correctly when all items have hints", function (assert) {
const dagMap = new DAGMap();
dagMap.add("key1", null, { after: "key2" });
dagMap.add("key2", null, { before: "key3" });
dagMap.add("key3", null, { before: "key1" });
const sorted = dagMap.sort();
assert.deepEqual(sorted, ["key2", "key3", "key1"]);
});
test("Items are positioned just after the specified item", function (assert) {
const dagMap = new DAGMap();
dagMap.add("key1");

View File

@@ -279,7 +279,7 @@ module("Unit | Lib | DAG", function (hooks) {
const dag = new DAG();
dag.add("key1", "value1");
dag.add("key2", "value2", { before: "key1" });
dag.add("key3", "value3");
dag.add("key3", "value3", { after: "key1" });
dag.delete("key1");