<commit_before>/**
# graphlib api documentation
**/
/*
 * This file is organized with in the following order:
 *
 * Exports
 * Graph constructors
 * Graph queries (e.g. nodes(), edges()
 * Graph mutators
 * Helper functions
 */

module.exports = Graph;

/**
  ## new Graph()
  A directed multi-graph.
**/
function Graph() {
  /* Map of nodeId -> {id, value} */
  this._nodes = {};

  /* Map of sourceId -> {targetId -> {count, edgeId -> true}} */
  this._inEdges = {};

  /* Map of targetId -> {sourceId -> {count, edgeId -> true}} */
  this._outEdges = {};

  /* Map of edgeId -> {id, source, target, value} */
  this._edges = {};

  /* Used to generate anonymous edge ids */
  this._nextEdgeId = 0;
}

/**
  ### Subgraph(us)

  Constructs and returns a new graph that includes only the nodes in `us`. Any
  edges that have both their source and target in the set `us` are also
  included in the subgraph.
 
  Changes to the graph itself are not reflected in the original graph.
  However, the values for nodes and edges are not copied. If the values are
  objects then their changes will be reflected in the original graph and the
  subgraph.
 
  If any of the nodes in `us` are not in this graph this function raises an
  Error.
**/
Graph.prototype.subgraph = function(us) {
  var g = new Graph();
  var self = this;

  us.forEach(function(u) { g.addNode(u, self.node(u)); });
  values(this._edges).forEach(function(e) {
    if (g.hasNode(e.source) && g.hasNode(e.target)) {
      g.addEdge(e.id, e.source, e.target, self.edge(e.id));
    }
  });

  return g;
};

/**
  ### Graph#order()
  Returns the number of nodes in this graph.
**/
Graph.prototype.order = function() {
  return Object.keys(this._nodes).length;
};

/*
 * Returns the number of edges in this graph.
 */
Graph.prototype.size = function() {
  return Object.keys(this._edges).length;
};

/*
  ### Graph#hasNode(u)

  Returns `true` if this graph contains a node with the id `u`. Otherwise
  returns false.
**/
Graph.prototype.hasNode = function(u) {
  return u in this._nodes;
};

/**
  ### Graph#node(u)
  Returns the value for a node in the graph with the id `u`. If no such node
  is in the graph this function will throw an Error.
**/
Graph.prototype.node = function(u) {
  return this._strictGetNode(u).value;
};

/**
  ### Graph#nodes()
  Returns the ids of all nodes in this graph. Use `graph.node(u)` to get the
  value for a specific node.
**/

Graph.prototype.nodes = function() {
  var nodes = [];
  this.eachNode(function(id, _) { nodes.push(id); });
  return nodes;
};

/**
  ### Graph#eachNode(func)
  Applies a function that takes the parameters (`id`, `value`) to each node in
  the graph in arbitrary order.
**/

Graph.prototype.eachNode = function(func) {
  for (var k in this._nodes) {
    var node = this._nodes[k];
    func(node.id, node.value);
  }
};

/**
  ### Graph#successors(u)

  Returns all successors of the node with the id `u`. That is, all nodes
  that have the node `u` as their source are returned.
 
  If no node `u` exists in the graph this function throws an Error.
**/

Graph.prototype.successors = function(u) {
  this._strictGetNode(u);
  return Object.keys(this._outEdges[u])
               .map(function(v) { return this._nodes[v].id; }, this);
};

/*
  ### Graph#predecessors(u)

  Returns all predecessors of the node with the id `u`. That is, all nodes
  that have the node `u` as their target are returned.
 
  If no node `u` exists in the graph this function throws an Error.
**/
Graph.prototype.predecessors = function(u) {
  this._strictGetNode(u);
  return Object.keys(this._inEdges[u])
               .map(function(v) { return this._nodes[v].id; }, this);
};

/**
  ### Graph#neighbors(u)

  Returns all nodes that are adjacent to the node with the id `u`. In other
  words, this function returns the set of all successors and predecessors of
  node `u`.
**/
Graph.prototype.neighbors = function(u) {
  this._strictGetNode(u);
  var vs = {};

  Object.keys(this._outEdges[u])
        .map(function(v) { vs[v] = true; });

  Object.keys(this._inEdges[u])
        .map(function(v) { vs[v] = true; });

  return Object.keys(vs)
               .map(function(v) { return this._nodes[v].id; }, this);
};

/**
  ### Graph#sources()

  Returns all nodes in the graph that have no in-edges.
**/
Graph.prototype.sources = function() {
  var self = this;
  return this._filterNodes(function(u) {
    // This could have better space characteristics if we had an inDegree function.
    return self.inEdges(u).length === 0;
  });
};

/**
  ### Graph#sinks()

  Returns all nodes in the graph that have no out-edges.
*/
Graph.prototype.sinks = function() {
  var self = this;
  return this._filterNodes(function(u) {
    // This could have better space characteristics if we have an outDegree function.
    return self.outEdges(u).length === 0;
  });
};

/**
  ### Graph#hasEdge(e)<commit_msg>fix doc comments<commit_after>/**
# graphlib api documentation
**/
/*
 * This file is organized with in the following order:
 *
 * Exports
 * Graph constructors
 * Graph queries (e.g. nodes(), edges()
 * Graph mutators
 * Helper functions
 */

module.exports = Graph;

/**
  ## new Graph()
  A directed multi-graph.
**/
function Graph() {
  /* Map of nodeId -> {id, value} */
  this._nodes = {};

  /* Map of sourceId -> {targetId -> {count, edgeId -> true}} */
  this._inEdges = {};

  /* Map of targetId -> {sourceId -> {count, edgeId -> true}} */
  this._outEdges = {};

  /* Map of edgeId -> {id, source, target, value} */
  this._edges = {};

  /* Used to generate anonymous edge ids */
  this._nextEdgeId = 0;
}

/**
  ### Subgraph(us)

  Constructs and returns a new graph that includes only the nodes in `us`. Any
  edges that have both their source and target in the set `us` are also
  included in the subgraph.
 
  Changes to the graph itself are not reflected in the original graph.
  However, the values for nodes and edges are not copied. If the values are
  objects then their changes will be reflected in the original graph and the
  subgraph.
 
  If any of the nodes in `us` are not in this graph this function raises an
  Error.
**/
Graph.prototype.subgraph = function(us) {
  var g = new Graph();
  var self = this;

  us.forEach(function(u) { g.addNode(u, self.node(u)); });
  values(this._edges).forEach(function(e) {
    if (g.hasNode(e.source) && g.hasNode(e.target)) {
      g.addEdge(e.id, e.source, e.target, self.edge(e.id));
    }
  });

  return g;
};

/**
  ### Graph#order()
  Returns the number of nodes in this graph.
**/
Graph.prototype.order = function() {
  return Object.keys(this._nodes).length;
};

/**
  ### Graph#size
  Returns the number of edges in this graph.
**/
Graph.prototype.size = function() {
  return Object.keys(this._edges).length;
};

/**
  ### Graph#hasNode(u)
  Returns `true` if this graph contains a node with the id `u`. Otherwise
  returns false.
**/
Graph.prototype.hasNode = function(u) {
  return u in this._nodes;
};

/**
  ### Graph#node(u)
  Returns the value for a node in the graph with the id `u`. If no such node
  is in the graph this function will throw an Error.
**/
Graph.prototype.node = function(u) {
  return this._strictGetNode(u).value;
};

/**
  ### Graph#nodes()
  Returns the ids of all nodes in this graph. Use `graph.node(u)` to get the
  value for a specific node.
**/

Graph.prototype.nodes = function() {
  var nodes = [];
  this.eachNode(function(id, _) { nodes.push(id); });
  return nodes;
};

/**
  ### Graph#eachNode(func)
  Applies a function that takes the parameters (`id`, `value`) to each node in
  the graph in arbitrary order.
**/

Graph.prototype.eachNode = function(func) {
  for (var k in this._nodes) {
    var node = this._nodes[k];
    func(node.id, node.value);
  }
};

/**
  ### Graph#successors(u)

  Returns all successors of the node with the id `u`. That is, all nodes
  that have the node `u` as their source are returned.
 
  If no node `u` exists in the graph this function throws an Error.
**/

Graph.prototype.successors = function(u) {
  this._strictGetNode(u);
  return Object.keys(this._outEdges[u])
               .map(function(v) { return this._nodes[v].id; }, this);
};

/**
  ### Graph#predecessors(u)

  Returns all predecessors of the node with the id `u`. That is, all nodes
  that have the node `u` as their target are returned.
 
  If no node `u` exists in the graph this function throws an Error.
**/
Graph.prototype.predecessors = function(u) {
  this._strictGetNode(u);
  return Object.keys(this._inEdges[u])
               .map(function(v) { return this._nodes[v].id; }, this);
};

/**
  ### Graph#neighbors(u)

  Returns all nodes that are adjacent to the node with the id `u`. In other
  words, this function returns the set of all successors and predecessors of
  node `u`.
**/
Graph.prototype.neighbors = function(u) {
  this._strictGetNode(u);
  var vs = {};

  Object.keys(this._outEdges[u])
        .map(function(v) { vs[v] = true; });

  Object.keys(this._inEdges[u])
        .map(function(v) { vs[v] = true; });

  return Object.keys(vs)
               .map(function(v) { return this._nodes[v].id; }, this);
};

/**
  ### Graph#sources()

  Returns all nodes in the graph that have no in-edges.
**/
Graph.prototype.sources = function() {
  var self = this;
  return this._filterNodes(function(u) {
    // This could have better space characteristics if we had an inDegree function.
    return self.inEdges(u).length === 0;
  });
};

/**
  ### Graph#sinks()

  Returns all nodes in the graph that have no out-edges.
**/
Graph.prototype.sinks = function() {
  var self = this;
  return this._filterNodes(function(u) {
    // This could have better space characteristics if we have an outDegree function.
    return self.outEdges(u).length === 0;
  });
};

/**
  ### Graph#hasEdge(e)
{'fraction_non_alphanumeric': 0.14355528405620036, 'fraction_numerical': 0.0006108735491753207, 'mean_word_length': 3.142977646562632, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 19, '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': '447378', 'n_tokens_mistral': 3192, 'n_tokens_neox': 3149, 'n_words': 1066}