<commit_before>function Graph() {
  this._nodes = {};
  this._edges = [];
};

Graph.prototype.setNode = function(id, value) {
  this._nodes[id] = value;
};

Graph.prototype.addEdge = function(sourceId, targetId, key) {
  var source = this._nodes[sourceId];
  if (source === undefined) {
    throw "source node does not exist: " + sourceId;
  }

  var target = this._nodes[targetId];
  if (target === undefined) {
    throw "target node does not exist: " + targetId;
  }

  if (source._edgeKeys.indexOf(key) == -1) {
    source._edgeKeys.push(key);
  }

  if (target._edgeKeys.indexOf(key) == -1) {
    target._edgeKeys.push(key);
  }

  var edgeSource = source._edgeSources[key];
  if (!edgeSource) {
    edgeSource = new EdgeSource(source, key);
    source._edgeSources[key] = edgeSource;
  }

  var edgeTarget = target._edgeTargets[key];
  if (!edgeTarget) {
    edgeTarget = new EdgeTarget(target, key);
    target._edgeTargets[key] = edgeTarget;
  }

  var edge = new Edge(edgeSource, edgeTarget);
  target._inEdges.push(edge);
  source._outEdges.push(edge);
  this._edges.push(edge);

  source._clearCaches();
  target._clearCaches();
}

Graph.prototype.node = function(id) {
  return this._nodes[id];
};

Graph.prototype.nodes = function() {
  var nodes = [];

  for (var id in this._nodes) {
    nodes.push(this._nodes[id]);
  }

  return nodes;
};

Graph.prototype.edges = function() {
  return this._edges;
};

Graph.prototype.layout = function() {
  var columns = {};

  for (var i in this._nodes) {
    var node = this._nodes[i];

    var columnIdx = node.column();
    var column = columns[columnIdx];
    if (!column) {
      column = new Column();
      columns[columnIdx] = column;
    }

    column.nodes.push(node);
  }

  for (var c in columns)
    columns[c]._cacheEdges()

  for (var i in this._nodes) {
    var node = this._nodes[i];

    var column = node.column();

    var columnOffset = 0;
    for (var c in columns) {
      if (c < column) {
        columnOffset += columns[c].width() + 50;
      }
    }

    node._position.x = columnOffset + ((columns[column].width() - node.width()) / 2);

    node._edgeKeys.sort(function(a, b) {
      var targetA = node._edgeTargets[a];
      var targetB = node._edgeTargets[b];

      var aIsConnected = targetA && targetA.isConnected();
      var bIsConnected = targetB && targetB.isConnected();

      if (aIsConnected) {
        if (bIsConnected) {
          return a.localeCompare(b);
        } else {
          return -1;
        }
      } else {
        if (bIsConnected) {
          return 1;
        } else {
          return a.localeCompare(b);
        }
      }
    });
  }

  for (var c in columns) {
    columns[c].layout();
  }

  for (var i = 0; i < 10; i++) {
    for (var c in columns) {
      columns[c].improve();
    }
  }
}

function Column() {
  this.nodes = [];

  this._spacing = 10;
}

Column.prototype.improve = function() {
  var nodes = this.nodes;

  for (var i = 0; i < nodes.length; i++) {
    var nodeIdx = i;

    for (var j = 0; j < nodes.length; j++) {
      if (nodeIdx == j) {
        continue;
      }

      var crossingBefore = this.crossingLines();
      var before = crossingBefore.inputs + crossingBefore.outputs;
      var beforeCost = this.cost();

      this.swap(nodeIdx, j)

      var crossingAfter = this.crossingLines();
      var after = crossingAfter.inputs + crossingAfter.outputs;
      var afterCost = this.cost();

      if (
        // fewer crossing overall
        after < before ||

        // same crossing but fewer crossing inputs (next column may fix outputs)
        (after == before && crossingAfter.inputs < crossingBefore.inputs) ||

        // same crossing but nodes are closer
        (after == before && afterCost < beforeCost) ||

        // nodes are closer by a significant amount
        (beforeCost - afterCost > 50)
      ) {
        nodeIdx = j;
      } else {
        this.swap(nodeIdx, j)
      }
    }
  }
}

Column.prototype.swap = function(a, b) {
  var tmp = this.nodes[a];
  this.nodes[a] = this.nodes[b];
  this.nodes[b] = tmp;
<commit_msg>simplify ordering logic<commit_after>function Graph() {
  this._nodes = {};
  this._edges = [];
};

Graph.prototype.setNode = function(id, value) {
  this._nodes[id] = value;
};

Graph.prototype.addEdge = function(sourceId, targetId, key) {
  var source = this._nodes[sourceId];
  if (source === undefined) {
    throw "source node does not exist: " + sourceId;
  }

  var target = this._nodes[targetId];
  if (target === undefined) {
    throw "target node does not exist: " + targetId;
  }

  if (source._edgeKeys.indexOf(key) == -1) {
    source._edgeKeys.push(key);
  }

  if (target._edgeKeys.indexOf(key) == -1) {
    target._edgeKeys.push(key);
  }

  var edgeSource = source._edgeSources[key];
  if (!edgeSource) {
    edgeSource = new EdgeSource(source, key);
    source._edgeSources[key] = edgeSource;
  }

  var edgeTarget = target._edgeTargets[key];
  if (!edgeTarget) {
    edgeTarget = new EdgeTarget(target, key);
    target._edgeTargets[key] = edgeTarget;
  }

  var edge = new Edge(edgeSource, edgeTarget);
  target._inEdges.push(edge);
  source._outEdges.push(edge);
  this._edges.push(edge);

  source._clearCaches();
  target._clearCaches();
}

Graph.prototype.node = function(id) {
  return this._nodes[id];
};

Graph.prototype.nodes = function() {
  var nodes = [];

  for (var id in this._nodes) {
    nodes.push(this._nodes[id]);
  }

  return nodes;
};

Graph.prototype.edges = function() {
  return this._edges;
};

Graph.prototype.layout = function() {
  var columns = {};

  for (var i in this._nodes) {
    var node = this._nodes[i];

    var columnIdx = node.column();
    var column = columns[columnIdx];
    if (!column) {
      column = new Column();
      columns[columnIdx] = column;
    }

    column.nodes.push(node);
  }

  for (var c in columns)
    columns[c]._cacheEdges()

  for (var i in this._nodes) {
    var node = this._nodes[i];

    var column = node.column();

    var columnOffset = 0;
    for (var c in columns) {
      if (c < column) {
        columnOffset += columns[c].width() + 50;
      }
    }

    node._position.x = columnOffset + ((columns[column].width() - node.width()) / 2);

    node._edgeKeys.sort(function(a, b) {
      var targetA = node._edgeTargets[a];
      var targetB = node._edgeTargets[b];

      var aIsConnected = targetA && targetA.isConnected();
      var bIsConnected = targetB && targetB.isConnected();

      if (aIsConnected) {
        if (bIsConnected) {
          return a.localeCompare(b);
        } else {
          return -1;
        }
      } else {
        if (bIsConnected) {
          return 1;
        } else {
          return a.localeCompare(b);
        }
      }
    });
  }

  for (var c in columns) {
    columns[c].layout();
  }

  for (var i = 0; i < 10; i++) {
    for (var c in columns) {
      columns[c].improve();
    }
  }
}

function Column() {
  this.nodes = [];

  this._spacing = 10;
}

Column.prototype.improve = function() {
  var nodes = this.nodes;

  for (var i = 0; i < nodes.length; i++) {
    var nodeIdx = i;

    for (var j = 0; j < nodes.length; j++) {
      if (nodeIdx == j) {
        continue;
      }

      var crossingBefore = this.crossingLines();
      var before = crossingBefore.inputs + crossingBefore.outputs;
      var beforeCost = this.cost();

      this.swap(nodeIdx, j)

      var crossingAfter = this.crossingLines();
      var after = crossingAfter.inputs + crossingAfter.outputs;
      var afterCost = this.cost();

      if (
        // fewer crossing overall
        after < before ||

        // same crossing but fewer crossing inputs (next column may fix outputs)
        (after == before && crossingAfter.inputs < crossingBefore.inputs) ||

        // same crossing but nodes are closer
        (after == before && afterCost < beforeCost)
      ) {
        nodeIdx = j;
      } else {
        this.swap(nodeIdx, j)
      }
    }
  }
}

Column.prototype.swap = function(a, b) {
  var tmp = this.nodes[a];
  this.nodes[a] = this.nodes[b];
  this.nodes[b] = tmp;

{'fraction_non_alphanumeric': 0.1434567901234568, 'fraction_numerical': 0.003950617283950617, 'mean_word_length': 2.4487015751383567, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 4, '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': '714368', 'n_tokens_mistral': 2712, 'n_tokens_neox': 2607, 'n_words': 636}