<commit_before>'use strict'

const bindings = require('bindings')
const binding = bindings('sample_heap')
// const binding = require('/Users/thlorenz/Library/Developer/Xcode/DerivedData/binding-azowbesvlizacoezrbwrtpuhbiit/Build/Products/Debug/sample_heap.node')

/**
 * Starts sampling of memory allocations
 *
 * @name startSampling
 * @function
 * @param {number} interval the sampling interval in ms, default: 32
 * @param {number} stack_depth depth of stack to include for each memory allocation, default: 6
 */
exports.startSampling = function startSampling(interval = 32, stack_depth = 6) {
  // todo: ensure these are integers
  binding.startSampling(interval, stack_depth)
}

/**
 * Stops sampling of memory allocations
 *
 * @name stopSampling
 * @function
 */
exports.stopSampling = function stopSampling() {
  binding.stopSampling()
}

/**
 * Visits all nodes and returns a flat array of them.
 * Each has an id and an array of ids of its children.
 * It has another array of allocations associated with that node.
 *
 * @name visitNodes
 * @function
 * @return Array.<Object> nodes found
 */
exports.visitNodes = function visitNodes() {
  const nodes = []
  let currentNode = null

  function onnode(id,
                  script_id,
                  script_name,
                  name,
                  line_number,
                  column_number) {
    currentNode = {
      id,
      script_id,
      script_name,
      name,
      line_number,
      column_number,
      allocations: [],
      children: []
    }
    nodes.push(currentNode)
  }

  function onallocation(count, size) {
    currentNode.allocations.push({ count, size })
  }

  function onchild(child) {
    currentNode.children.push(child)
  }

  binding.visitNodes(onnode, onallocation, onchild)
  return nodes<commit_msg>core: reconstruct callgraph implemntation<commit_after>'use strict'

const bindings = require('bindings')
const binding = bindings('sample_heap')

/**
 * Starts sampling of memory allocations
 *
 * @name startSampling
 * @function
 * @param {number} interval the sampling interval in ms, default: 32
 * @param {number} stack_depth depth of stack to include for each memory allocation, default: 6
 */
exports.startSampling = function startSampling(interval = 32, stack_depth = 6) {
  // todo: ensure these are integers
  binding.startSampling(interval, stack_depth)
}

/**
 * Stops sampling of memory allocations
 *
 * @name stopSampling
 * @function
 */
exports.stopSampling = function stopSampling() {
  binding.stopSampling()
}

/**
 * Visits all nodes and returns a flat array of them.
 * Each has an id and an array of ids of its children.
 * It has another array of allocations associated with that node.
 *
 * @name visitNodes
 * @function
 * @return Array.<Object> nodes found
 */
exports.visitNodes = function visitNodes() {
  const nodes = []
  let currentNode = null

  function onnode(id,
                  script_id,
                  script_name,
                  name,
                  line_number,
                  column_number) {
    currentNode = {
      id,
      script_id,
      script_name,
      name,
      line_number,
      column_number,
      allocations: [],
      child_ids: []
    }
    nodes.push(currentNode)
  }

  function onallocation(count, size) {
    currentNode.allocations.push({ count, size })
  }

  function onchild(child) {
    currentNode.child_ids.push(child)
  }

  binding.visitNodes(onnode, onallocation, onchild)
  return nodes
}

function processNode(hash, node) {
  function getChild(id) { return hash[id] }
  node.children = node.child_ids.map(getChild)

  function processChild(child) {
    processNode(hash, child)
  }
  node.children.forEach(processChild)
}

/**
 * Reconstructs the callgraph from the nodes array obtained via @see visitNodes.
 *
 * @name constructCallgraph
 * @function
 * @param {Array.<Object>} nodes obtained via @see visitNodes
 * @return {Object} the callgraph including all allocation information
 */
exports.constructCallgraph = function constructCallgraph(nodes) {
  function hashify(acc, node) {
    acc[node.id] = node
    return acc
  }
  const hash = nodes.reduce(hashify, {})

  const rootnode_id = '0:0:0'
  const rootnode = hash[rootnode_id]
  processNode(hash, rootnode)
  return rootnode
{'fraction_non_alphanumeric': 0.09813519813519814, 'fraction_numerical': 0.0034965034965034965, 'mean_word_length': 3.166019417475728, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1176705', 'n_tokens_mistral': 1285, 'n_tokens_neox': 1242, 'n_words': 357}