You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					107 lines
				
				2.2 KiB
			
		
		
			
		
	
	
					107 lines
				
				2.2 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								'use strict'
							 | 
						||
| 
								 | 
							
								const archy = require('archy')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function TimeTree () {
							 | 
						||
| 
								 | 
							
								  this.root = null
							 | 
						||
| 
								 | 
							
								  this.tableId = new Map()
							 | 
						||
| 
								 | 
							
								  this.tableLabel = new Map()
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								TimeTree.prototype.trackNode = function (node) {
							 | 
						||
| 
								 | 
							
								  this.tableId.set(node.id, node)
							 | 
						||
| 
								 | 
							
								  if (this.tableLabel.has(node.label)) {
							 | 
						||
| 
								 | 
							
								    this.tableLabel.get(node.label).push(node)
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    this.tableLabel.set(node.label, [node])
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								TimeTree.prototype.untrackNode = function (node) {
							 | 
						||
| 
								 | 
							
								  this.tableId.delete(node.id)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const labelNode = this.tableLabel.get(node.label)
							 | 
						||
| 
								 | 
							
								  if (labelNode.id) {
							 | 
						||
| 
								 | 
							
								    this.tableLabel.delete(node.label)
							 | 
						||
| 
								 | 
							
								    return
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  labelNode.pop()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (labelNode.length === 0) {
							 | 
						||
| 
								 | 
							
								    this.tableLabel.delete(node.label)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								TimeTree.prototype.getParent = function (parent) {
							 | 
						||
| 
								 | 
							
								  if (parent === null) {
							 | 
						||
| 
								 | 
							
								    return this.root
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const parentNode = this.tableLabel.get(parent)
							 | 
						||
| 
								 | 
							
								  if (parentNode.id) {
							 | 
						||
| 
								 | 
							
								    return parentNode
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  return parentNode[parentNode.length - 1]
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								TimeTree.prototype.getNode = function (nodeId) {
							 | 
						||
| 
								 | 
							
								  return this.tableId.get(nodeId)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								TimeTree.prototype.add = function (parent, child, start) {
							 | 
						||
| 
								 | 
							
								  const isRoot = parent === null
							 | 
						||
| 
								 | 
							
								  if (isRoot) {
							 | 
						||
| 
								 | 
							
								    this.root = {
							 | 
						||
| 
								 | 
							
								      id: 'root',
							 | 
						||
| 
								 | 
							
								      label: child,
							 | 
						||
| 
								 | 
							
								      start,
							 | 
						||
| 
								 | 
							
								      nodes: []
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    this.trackNode(this.root)
							 | 
						||
| 
								 | 
							
								    return this.root.id
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const parentNode = this.getParent(parent)
							 | 
						||
| 
								 | 
							
								  const nodeId = `${child}-${Math.random()}`
							 | 
						||
| 
								 | 
							
								  const childNode = {
							 | 
						||
| 
								 | 
							
								    id: nodeId,
							 | 
						||
| 
								 | 
							
								    parent,
							 | 
						||
| 
								 | 
							
								    start,
							 | 
						||
| 
								 | 
							
								    label: child,
							 | 
						||
| 
								 | 
							
								    nodes: []
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  parentNode.nodes.push(childNode)
							 | 
						||
| 
								 | 
							
								  this.trackNode(childNode)
							 | 
						||
| 
								 | 
							
								  return nodeId
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								TimeTree.prototype.start = function (parent, child, start) {
							 | 
						||
| 
								 | 
							
								  return this.add(parent, child, start || Date.now())
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								TimeTree.prototype.stop = function (nodeId, stop) {
							 | 
						||
| 
								 | 
							
								  const node = this.getNode(nodeId)
							 | 
						||
| 
								 | 
							
								  if (node) {
							 | 
						||
| 
								 | 
							
								    node.stop = stop || Date.now()
							 | 
						||
| 
								 | 
							
								    node.diff = (node.stop - node.start) || 0
							 | 
						||
| 
								 | 
							
								    this.untrackNode(node)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								TimeTree.prototype.toJSON = function () {
							 | 
						||
| 
								 | 
							
								  return Object.assign({}, this.root)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								TimeTree.prototype.prittyPrint = function () {
							 | 
						||
| 
								 | 
							
								  const decorateText = (node) => {
							 | 
						||
| 
								 | 
							
								    node.label = `${node.label} ${node.diff} ms`
							 | 
						||
| 
								 | 
							
								    if (node.nodes.length > 0) {
							 | 
						||
| 
								 | 
							
								      node.nodes = node.nodes.map(_ => decorateText(_))
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return node
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  const out = decorateText(this.toJSON())
							 | 
						||
| 
								 | 
							
								  return archy(out)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = TimeTree
							 |