<commit_before>'use strict';

const assert = require('assert');

class TopologicalSort {

    constructor(nodes) {
        this._nodes = new Map;
        this._addNodes(nodes);
    }

    addNode(key, node) {
        return this._addNode(key, node);
    }

    addNodes(nodes) {
        this._addNodes(nodes);
    }

    addEdge(fromKey, toKey) {
        assert(this._nodes.has(fromKey), `Source node with ${fromKey} key should exist`);
        assert(this._nodes.has(toKey), `Target node with ${toKey} key should exist`);

        const sourceNode = this._nodes.get(fromKey);
        const targetNode = this._nodes.get(toKey);

        assert.strictEqual(sourceNode !== undefined, true, `Source node with key ${fromKey} doesn't exist`);
        assert.strictEqual(targetNode !== undefined, true, `Target node with key ${toKey} doesn't exist`);
        assert.strictEqual(sourceNode.children.has(toKey), false, `Source node ${fromKey} already has an adge to target node ${toKey}`);

        sourceNode.children.set(toKey, targetNode);
    }

    sort() {
        const visitedNodes = new Set;
        const sortedKeysStack = [];
        const output = new Map;

        for (const [key] of this._nodes) {
            this._exploreNode(key, visitedNodes, sortedKeysStack);
        }

        for (let i = sortedKeysStack.length - 1; i >= 0; i--) {
            output.set(sortedKeysStack[i], this._nodes.get(sortedKeysStack[i]));
        }

        return output;
    }

    _exploreNode(nodeKey, visitedNodesRef, stackRef) {
        const node = this._nodes.get(nodeKey);

        if (visitedNodesRef.has(node)) {
            return;
        }

        // mark node as visited so that it and its children
        // won't be explored next time
        visitedNodesRef.add(node);

        for (const [childNodeKey] of node.children) {
            this._exploreNode(childNodeKey, visitedNodesRef, stackRef);
        }

        stackRef.push(nodeKey);
    }

    _addNode(key, node) {
        assert.strictEqual(this._nodes.has(key), false, `Node ${key} already exists`);

        // TODO: check circular dependencies<commit_msg>Refactoring: _exploreNode private API is now invoked with nodeKey only<commit_after>'use strict';

const assert = require('assert');

class TopologicalSort {

    constructor(nodes) {
        this._nodes = new Map;
        this._addNodes(nodes);
    }

    addNode(key, node) {
        return this._addNode(key, node);
    }

    addNodes(nodes) {
        this._addNodes(nodes);
    }

    addEdge(fromKey, toKey) {
        assert(this._nodes.has(fromKey), `Source node with ${fromKey} key should exist`);
        assert(this._nodes.has(toKey), `Target node with ${toKey} key should exist`);

        const sourceNode = this._nodes.get(fromKey);
        const targetNode = this._nodes.get(toKey);

        assert.strictEqual(sourceNode !== undefined, true, `Source node with key ${fromKey} doesn't exist`);
        assert.strictEqual(targetNode !== undefined, true, `Target node with key ${toKey} doesn't exist`);
        assert.strictEqual(sourceNode.children.has(toKey), false, `Source node ${fromKey} already has an adge to target node ${toKey}`);

        sourceNode.children.set(toKey, targetNode);
    }

    sort() {
        this._visitedNodes = new Set;
        this._sortedKeysStack = [];
        const output = new Map;

        for (const [key] of this._nodes) {
            this._exploreNode(key);
        }

        for (let i = this._sortedKeysStack.length - 1; i >= 0; i--) {
            output.set(this._sortedKeysStack[i], this._nodes.get(this._sortedKeysStack[i]));
        }

        return output;
    }

    _exploreNode(nodeKey) {
        const node = this._nodes.get(nodeKey);

        if (this._visitedNodes.has(node)) {
            return;
        }

        // mark node as visited so that it and its children
        // won't be explored next time
        this._visitedNodes.add(node);

        for (const [childNodeKey] of node.children) {
            this._exploreNode(childNodeKey);
        }

        this._sortedKeysStack.push(nodeKey);
    }

    _addNode(key, node) {
        assert.strictEqual(this._nodes.has(key), false, `Node ${key} already exists`);

        // TODO: check circular dependencies
{'fraction_non_alphanumeric': 0.12232918525475464, 'fraction_numerical': 0.0009391876027236441, 'mean_word_length': 2.4918032786885247, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '386512', 'n_tokens_mistral': 1272, 'n_tokens_neox': 1240, 'n_words': 310}