From fae2d8199dbb364e57d28e0e4f1df313f54528e1 Mon Sep 17 00:00:00 2001 From: "Lin, Hung-Shin" Date: Wed, 15 Nov 2023 14:30:37 +0800 Subject: [PATCH] feat: calculate layer --- packages/utils/dag.js | 30 +++++++++++++++++++++++ packages/utils/dag.test.js | 50 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 packages/utils/dag.js create mode 100644 packages/utils/dag.test.js diff --git a/packages/utils/dag.js b/packages/utils/dag.js new file mode 100644 index 0000000..22369b4 --- /dev/null +++ b/packages/utils/dag.js @@ -0,0 +1,30 @@ +export default class DAG { + constructor(nodes) { + this.nodes = new Map(nodes.map((node) => [node._id, node])) + this.edges = [] + } + + setLayer(id) { + console.log(`setLayer(${id})`) + const node = this.nodes.get(id) + if (!node) { + throw new Error(`Node ${id} not found`) + } + if (node.layer !== undefined) { + return node.layer + } + const previousLayer = node.requirements.map((rId) => this.setLayer(rId)) + node.layer = Math.max(...previousLayer, 0) + 1 + return node.layer + } + + format() { + this.nodes.forEach((_, id) => { + this.setLayer(id) + }) + } + + get(id) { + return this.nodes.get(id) + } +} diff --git a/packages/utils/dag.test.js b/packages/utils/dag.test.js new file mode 100644 index 0000000..272eeea --- /dev/null +++ b/packages/utils/dag.test.js @@ -0,0 +1,50 @@ +import DAG from './dag.js' + +describe('dag', () => { + const data = [ + { + _id: 'helloworld', + title: 'Hello, Linux World!', + requirements: [], + }, + { + _id: 'spell', + title: 'Learn to spell', + requirements: ['helloworld'], + }, + { + _id: 'discover', + title: 'Discover the World!', + requirements: ['spell'], + }, + { + _id: 'read', + title: 'Read the File', + requirements: ['spell'], + }, + { + _id: 'remove', + requirements: ['read', 'discover'], + }, + { + _id: 'move', + requirements: ['helloworld'], + }, + { + _id: 'copy', + requirements: ['remove', 'move'], + }, + ] + + it('should set layers', () => { + const dag = new DAG(data) + dag.format() + expect(dag.get('helloworld').layer).toBe(1) + expect(dag.get('spell').layer).toBe(2) + expect(dag.get('move').layer).toBe(2) + expect(dag.get('read').layer).toBe(3) + expect(dag.get('discover').layer).toBe(3) + expect(dag.get('remove').layer).toBe(4) + expect(dag.get('copy').layer).toBe(5) + }) +})