提交 cf9337d2 编写于 作者: J Johannes Rieken

💄 graph updates

上级 13c79c8c
...@@ -4,82 +4,82 @@ ...@@ -4,82 +4,82 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
'use strict'; 'use strict';
import objects = require('vs/base/common/types'); import {isEmptyObject} from 'vs/base/common/types';
import collections = require('vs/base/common/collections'); import {forEach, contains, lookup} from 'vs/base/common/collections';
export interface Node<T> { export interface Node<T> {
data:T; data: T;
incoming:{[key:string]:Node<T>}; incoming: { [key: string]: Node<T> };
outgoing:{[key:string]:Node<T>}; outgoing: { [key: string]: Node<T> };
} }
export function newNode<T>(data:T):Node<T> { function newNode<T>(data: T): Node<T> {
return { return {
data: data, data: data,
incoming: {}, incoming: {},
outgoing: {} outgoing: {}
}; };
} }
export class Graph<T> { export class Graph<T> {
private _nodes:{[key:string]:Node<T>} = Object.create(null); private _nodes: { [key: string]: Node<T> } = Object.create(null);
constructor(private _hashFn:(element:T)=>string) { constructor(private _hashFn: (element: T) => string) {
// empty // empty
} }
public roots():Node<T>[] { roots(): Node<T>[] {
var ret:Node<T>[] = []; var ret: Node<T>[] = [];
collections.forEach(this._nodes, entry => { forEach(this._nodes, entry => {
if(objects.isEmptyObject(entry.value.outgoing)) { if (isEmptyObject(entry.value.outgoing)) {
ret.push(entry.value); ret.push(entry.value);
} }
}); });
return ret; return ret;
} }
public traverse(start:T, inwards:boolean, callback:(data:T)=>void):void { traverse(start: T, inwards: boolean, callback: (data: T) => void): void {
var startNode = this.lookup(start); var startNode = this.lookup(start);
if(!startNode) { if (!startNode) {
return; return;
} }
this._traverse(startNode, inwards, {}, callback); this._traverse(startNode, inwards, {}, callback);
} }
private _traverse(node:Node<T>, inwards:boolean, seen:{[key:string]:boolean}, callback:(data:T)=>void):void { private _traverse(node: Node<T>, inwards: boolean, seen: { [key: string]: boolean }, callback: (data: T) => void): void {
var key = this._hashFn(node.data); var key = this._hashFn(node.data);
if(collections.contains(seen, key)) { if (contains(seen, key)) {
return; return;
} }
seen[key] = true; seen[key] = true;
callback(node.data); callback(node.data);
var nodes = inwards ? node.outgoing : node.incoming; var nodes = inwards ? node.outgoing : node.incoming;
collections.forEach(nodes, (entry) => this._traverse(entry.value, inwards, seen, callback)); forEach(nodes, (entry) => this._traverse(entry.value, inwards, seen, callback));
} }
public insertEdge(from:T, to:T):void { insertEdge(from: T, to: T): void {
var fromNode = this.lookupOrInsertNode(from), var fromNode = this.lookupOrInsertNode(from),
toNode = this.lookupOrInsertNode(to); toNode = this.lookupOrInsertNode(to);
fromNode.outgoing[this._hashFn(to)] = toNode; fromNode.outgoing[this._hashFn(to)] = toNode;
toNode.incoming[this._hashFn(from)] = fromNode; toNode.incoming[this._hashFn(from)] = fromNode;
} }
public removeNode(data:T):void { removeNode(data: T): void {
var key = this._hashFn(data); var key = this._hashFn(data);
delete this._nodes[key]; delete this._nodes[key];
collections.forEach(this._nodes, (entry) => { forEach(this._nodes, (entry) => {
delete entry.value.outgoing[key]; delete entry.value.outgoing[key];
delete entry.value.incoming[key]; delete entry.value.incoming[key];
}); });
} }
public lookupOrInsertNode(data:T):Node<T> { lookupOrInsertNode(data: T): Node<T> {
var key = this._hashFn(data), var key = this._hashFn(data),
node = collections.lookup(this._nodes, key); node = lookup(this._nodes, key);
if(!node) { if (!node) {
node = newNode(data); node = newNode(data);
this._nodes[key] = node; this._nodes[key] = node;
} }
...@@ -87,11 +87,11 @@ export class Graph<T> { ...@@ -87,11 +87,11 @@ export class Graph<T> {
return node; return node;
} }
public lookup(data:T):Node<T> { lookup(data: T): Node<T> {
return collections.lookup(this._nodes, this._hashFn(data)); return lookup(this._nodes, this._hashFn(data));
} }
public get length():number { get length(): number {
return Object.keys(this._nodes).length; return Object.keys(this._nodes).length;
} }
} }
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册