ngraph.graph
Advanced tools
Comparing version 18.0.3 to 19.0.0
@@ -48,10 +48,13 @@ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.createGraph = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ | ||
var nodes = typeof Object.create === 'function' ? Object.create(null) : {}, | ||
links = [], | ||
if (typeof Map !== 'function') { | ||
// TODO: Should we polyfill it ourselves? We don't use much operations there.. | ||
throw new Error('ngraph.graph requires `Map` to be defined. Please polyfill it before using ngraph'); | ||
} | ||
var nodes = new Map(); | ||
var links = [], | ||
// Hash of multi-edges. Used to track ids of edges between same nodes | ||
multiEdges = {}, | ||
nodesCount = 0, | ||
suspendEvents = 0, | ||
forEachNode = createNodeIterator(), | ||
createLink = options.multigraph ? createUniqueLink : createSingleLink, | ||
@@ -137,3 +140,3 @@ | ||
getNodesCount: function () { | ||
return nodesCount; | ||
return nodes.size; | ||
}, | ||
@@ -290,3 +293,2 @@ | ||
node = new Node(nodeId, data); | ||
nodesCount++; | ||
recordNodeChange(node, 'add'); | ||
@@ -298,3 +300,3 @@ } else { | ||
nodes[nodeId] = node; | ||
nodes.set(nodeId, node); | ||
@@ -306,3 +308,3 @@ exitModification(); | ||
function getNode(nodeId) { | ||
return nodes[nodeId]; | ||
return nodes.get(nodeId); | ||
} | ||
@@ -326,4 +328,3 @@ | ||
delete nodes[nodeId]; | ||
nodesCount--; | ||
nodes.delete(nodeId) | ||
@@ -477,3 +478,3 @@ recordNodeChange(node, 'remove'); | ||
quitFast = callback(nodes[linkedNodeId], link); | ||
quitFast = callback(nodes.get(linkedNodeId), link); | ||
if (quitFast) { | ||
@@ -490,3 +491,3 @@ return true; // Client does not need more iterations. Break now. | ||
if (link.fromId === nodeId) { | ||
quitFast = callback(nodes[link.toId], link); | ||
quitFast = callback(nodes.get(link.toId), link) | ||
if (quitFast) { | ||
@@ -516,34 +517,16 @@ return true; // Client does not need more iterations. Break now. | ||
function createNodeIterator() { | ||
// Object.keys iterator is 1.3x faster than `for in` loop. | ||
// See `https://github.com/anvaka/ngraph.graph/tree/bench-for-in-vs-obj-keys` | ||
// branch for perf test | ||
return Object.keys ? objectKeysIterator : forInIterator; | ||
} | ||
function objectKeysIterator(callback) { | ||
function forEachNode(callback) { | ||
if (typeof callback !== 'function') { | ||
return; | ||
throw new Error('Function is expected to iterate over graph nodes. You passed ' + callback); | ||
} | ||
var keys = Object.keys(nodes); | ||
for (var i = 0; i < keys.length; ++i) { | ||
if (callback(nodes[keys[i]])) { | ||
var valuesIterator = nodes.values(); | ||
var nextValue = valuesIterator.next(); | ||
while (!nextValue.done) { | ||
if (callback(nextValue.value)) { | ||
return true; // client doesn't want to proceed. Return. | ||
} | ||
nextValue = valuesIterator.next(); | ||
} | ||
} | ||
function forInIterator(callback) { | ||
if (typeof callback !== 'function') { | ||
return; | ||
} | ||
var node; | ||
for (node in nodes) { | ||
if (callback(nodes[node])) { | ||
return true; // client doesn't want to proceed. Return. | ||
} | ||
} | ||
} | ||
} | ||
@@ -598,13 +581,2 @@ | ||
function hashCode(str) { | ||
var hash = 0, i, chr, len; | ||
if (str.length == 0) return hash; | ||
for (i = 0, len = str.length; i < len; i++) { | ||
chr = str.charCodeAt(i); | ||
hash = ((hash << 5) - hash) + chr; | ||
hash |= 0; // Convert to 32bit integer | ||
} | ||
return hash; | ||
} | ||
function makeLinkId(fromId, toId) { | ||
@@ -611,0 +583,0 @@ return fromId.toString() + '👉 ' + toId.toString(); |
@@ -1,1 +0,1 @@ | ||
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.createGraph=f()}})(function(){var define,module,exports;return function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r}()({1:[function(require,module,exports){module.exports=createGraph;var eventify=require("ngraph.events");function createGraph(options){options=options||{};if("uniqueLinkId"in options){console.warn("ngraph.graph: Starting from version 0.14 `uniqueLinkId` is deprecated.\n"+"Use `multigraph` option instead\n","\n","Note: there is also change in default behavior: From now on each graph\n"+"is considered to be not a multigraph by default (each edge is unique).");options.multigraph=options.uniqueLinkId}if(options.multigraph===undefined)options.multigraph=false;var nodes=typeof Object.create==="function"?Object.create(null):{},links=[],multiEdges={},nodesCount=0,suspendEvents=0,forEachNode=createNodeIterator(),createLink=options.multigraph?createUniqueLink:createSingleLink,changes=[],recordLinkChange=noop,recordNodeChange=noop,enterModification=noop,exitModification=noop;var graphPart={addNode:addNode,addLink:addLink,removeLink:removeLink,removeNode:removeNode,getNode:getNode,getNodesCount:function(){return nodesCount},getLinksCount:function(){return links.length},getLinks:getLinks,forEachNode:forEachNode,forEachLinkedNode:forEachLinkedNode,forEachLink:forEachLink,beginUpdate:enterModification,endUpdate:exitModification,clear:clear,hasLink:getLink,hasNode:getNode,getLink:getLink};eventify(graphPart);monitorSubscribers();return graphPart;function monitorSubscribers(){var realOn=graphPart.on;graphPart.on=on;function on(){graphPart.beginUpdate=enterModification=enterModificationReal;graphPart.endUpdate=exitModification=exitModificationReal;recordLinkChange=recordLinkChangeReal;recordNodeChange=recordNodeChangeReal;graphPart.on=realOn;return realOn.apply(graphPart,arguments)}}function recordLinkChangeReal(link,changeType){changes.push({link:link,changeType:changeType})}function recordNodeChangeReal(node,changeType){changes.push({node:node,changeType:changeType})}function addNode(nodeId,data){if(nodeId===undefined){throw new Error("Invalid node identifier")}enterModification();var node=getNode(nodeId);if(!node){node=new Node(nodeId,data);nodesCount++;recordNodeChange(node,"add")}else{node.data=data;recordNodeChange(node,"update")}nodes[nodeId]=node;exitModification();return node}function getNode(nodeId){return nodes[nodeId]}function removeNode(nodeId){var node=getNode(nodeId);if(!node){return false}enterModification();var prevLinks=node.links;if(prevLinks){node.links=null;for(var i=0;i<prevLinks.length;++i){removeLink(prevLinks[i])}}delete nodes[nodeId];nodesCount--;recordNodeChange(node,"remove");exitModification();return true}function addLink(fromId,toId,data){enterModification();var fromNode=getNode(fromId)||addNode(fromId);var toNode=getNode(toId)||addNode(toId);var link=createLink(fromId,toId,data);links.push(link);addLinkToNode(fromNode,link);if(fromId!==toId){addLinkToNode(toNode,link)}recordLinkChange(link,"add");exitModification();return link}function createSingleLink(fromId,toId,data){var linkId=makeLinkId(fromId,toId);return new Link(fromId,toId,data,linkId)}function createUniqueLink(fromId,toId,data){var linkId=makeLinkId(fromId,toId);var isMultiEdge=multiEdges.hasOwnProperty(linkId);if(isMultiEdge||getLink(fromId,toId)){if(!isMultiEdge){multiEdges[linkId]=0}var suffix="@"+ ++multiEdges[linkId];linkId=makeLinkId(fromId+suffix,toId+suffix)}return new Link(fromId,toId,data,linkId)}function getLinks(nodeId){var node=getNode(nodeId);return node?node.links:null}function removeLink(link){if(!link){return false}var idx=indexOfElementInArray(link,links);if(idx<0){return false}enterModification();links.splice(idx,1);var fromNode=getNode(link.fromId);var toNode=getNode(link.toId);if(fromNode){idx=indexOfElementInArray(link,fromNode.links);if(idx>=0){fromNode.links.splice(idx,1)}}if(toNode){idx=indexOfElementInArray(link,toNode.links);if(idx>=0){toNode.links.splice(idx,1)}}recordLinkChange(link,"remove");exitModification();return true}function getLink(fromNodeId,toNodeId){var node=getNode(fromNodeId),i;if(!node||!node.links){return null}for(i=0;i<node.links.length;++i){var link=node.links[i];if(link.fromId===fromNodeId&&link.toId===toNodeId){return link}}return null}function clear(){enterModification();forEachNode(function(node){removeNode(node.id)});exitModification()}function forEachLink(callback){var i,length;if(typeof callback==="function"){for(i=0,length=links.length;i<length;++i){callback(links[i])}}}function forEachLinkedNode(nodeId,callback,oriented){var node=getNode(nodeId);if(node&&node.links&&typeof callback==="function"){if(oriented){return forEachOrientedLink(node.links,nodeId,callback)}else{return forEachNonOrientedLink(node.links,nodeId,callback)}}}function forEachNonOrientedLink(links,nodeId,callback){var quitFast;for(var i=0;i<links.length;++i){var link=links[i];var linkedNodeId=link.fromId===nodeId?link.toId:link.fromId;quitFast=callback(nodes[linkedNodeId],link);if(quitFast){return true}}}function forEachOrientedLink(links,nodeId,callback){var quitFast;for(var i=0;i<links.length;++i){var link=links[i];if(link.fromId===nodeId){quitFast=callback(nodes[link.toId],link);if(quitFast){return true}}}}function noop(){}function enterModificationReal(){suspendEvents+=1}function exitModificationReal(){suspendEvents-=1;if(suspendEvents===0&&changes.length>0){graphPart.fire("changed",changes);changes.length=0}}function createNodeIterator(){return Object.keys?objectKeysIterator:forInIterator}function objectKeysIterator(callback){if(typeof callback!=="function"){return}var keys=Object.keys(nodes);for(var i=0;i<keys.length;++i){if(callback(nodes[keys[i]])){return true}}}function forInIterator(callback){if(typeof callback!=="function"){return}var node;for(node in nodes){if(callback(nodes[node])){return true}}}}function indexOfElementInArray(element,array){if(!array)return-1;if(array.indexOf){return array.indexOf(element)}var len=array.length,i;for(i=0;i<len;i+=1){if(array[i]===element){return i}}return-1}function Node(id,data){this.id=id;this.links=null;this.data=data}function addLinkToNode(node,link){if(node.links){node.links.push(link)}else{node.links=[link]}}function Link(fromId,toId,data,id){this.fromId=fromId;this.toId=toId;this.data=data;this.id=id}function hashCode(str){var hash=0,i,chr,len;if(str.length==0)return hash;for(i=0,len=str.length;i<len;i++){chr=str.charCodeAt(i);hash=(hash<<5)-hash+chr;hash|=0}return hash}function makeLinkId(fromId,toId){return fromId.toString()+"👉 "+toId.toString()}},{"ngraph.events":2}],2:[function(require,module,exports){module.exports=function(subject){validateSubject(subject);var eventsStorage=createEventsStorage(subject);subject.on=eventsStorage.on;subject.off=eventsStorage.off;subject.fire=eventsStorage.fire;return subject};function createEventsStorage(subject){var registeredEvents=Object.create(null);return{on:function(eventName,callback,ctx){if(typeof callback!=="function"){throw new Error("callback is expected to be a function")}var handlers=registeredEvents[eventName];if(!handlers){handlers=registeredEvents[eventName]=[]}handlers.push({callback:callback,ctx:ctx});return subject},off:function(eventName,callback){var wantToRemoveAll=typeof eventName==="undefined";if(wantToRemoveAll){registeredEvents=Object.create(null);return subject}if(registeredEvents[eventName]){var deleteAllCallbacksForEvent=typeof callback!=="function";if(deleteAllCallbacksForEvent){delete registeredEvents[eventName]}else{var callbacks=registeredEvents[eventName];for(var i=0;i<callbacks.length;++i){if(callbacks[i].callback===callback){callbacks.splice(i,1)}}}}return subject},fire:function(eventName){var callbacks=registeredEvents[eventName];if(!callbacks){return subject}var fireArguments;if(arguments.length>1){fireArguments=Array.prototype.splice.call(arguments,1)}for(var i=0;i<callbacks.length;++i){var callbackInfo=callbacks[i];callbackInfo.callback.apply(callbackInfo.ctx,fireArguments)}return subject}}}function validateSubject(subject){if(!subject){throw new Error("Eventify cannot use falsy object as events subject")}var reservedWords=["on","fire","off"];for(var i=0;i<reservedWords.length;++i){if(subject.hasOwnProperty(reservedWords[i])){throw new Error("Subject cannot be eventified, since it already has property '"+reservedWords[i]+"'")}}}},{}]},{},[1])(1)}); | ||
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.createGraph=f()}})(function(){var define,module,exports;return function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r}()({1:[function(require,module,exports){module.exports=createGraph;var eventify=require("ngraph.events");function createGraph(options){options=options||{};if("uniqueLinkId"in options){console.warn("ngraph.graph: Starting from version 0.14 `uniqueLinkId` is deprecated.\n"+"Use `multigraph` option instead\n","\n","Note: there is also change in default behavior: From now on each graph\n"+"is considered to be not a multigraph by default (each edge is unique).");options.multigraph=options.uniqueLinkId}if(options.multigraph===undefined)options.multigraph=false;if(typeof Map!=="function"){throw new Error("ngraph.graph requires `Map` to be defined. Please polyfill it before using ngraph")}var nodes=new Map;var links=[],multiEdges={},suspendEvents=0,createLink=options.multigraph?createUniqueLink:createSingleLink,changes=[],recordLinkChange=noop,recordNodeChange=noop,enterModification=noop,exitModification=noop;var graphPart={addNode:addNode,addLink:addLink,removeLink:removeLink,removeNode:removeNode,getNode:getNode,getNodesCount:function(){return nodes.size},getLinksCount:function(){return links.length},getLinks:getLinks,forEachNode:forEachNode,forEachLinkedNode:forEachLinkedNode,forEachLink:forEachLink,beginUpdate:enterModification,endUpdate:exitModification,clear:clear,hasLink:getLink,hasNode:getNode,getLink:getLink};eventify(graphPart);monitorSubscribers();return graphPart;function monitorSubscribers(){var realOn=graphPart.on;graphPart.on=on;function on(){graphPart.beginUpdate=enterModification=enterModificationReal;graphPart.endUpdate=exitModification=exitModificationReal;recordLinkChange=recordLinkChangeReal;recordNodeChange=recordNodeChangeReal;graphPart.on=realOn;return realOn.apply(graphPart,arguments)}}function recordLinkChangeReal(link,changeType){changes.push({link:link,changeType:changeType})}function recordNodeChangeReal(node,changeType){changes.push({node:node,changeType:changeType})}function addNode(nodeId,data){if(nodeId===undefined){throw new Error("Invalid node identifier")}enterModification();var node=getNode(nodeId);if(!node){node=new Node(nodeId,data);recordNodeChange(node,"add")}else{node.data=data;recordNodeChange(node,"update")}nodes.set(nodeId,node);exitModification();return node}function getNode(nodeId){return nodes.get(nodeId)}function removeNode(nodeId){var node=getNode(nodeId);if(!node){return false}enterModification();var prevLinks=node.links;if(prevLinks){node.links=null;for(var i=0;i<prevLinks.length;++i){removeLink(prevLinks[i])}}nodes.delete(nodeId);recordNodeChange(node,"remove");exitModification();return true}function addLink(fromId,toId,data){enterModification();var fromNode=getNode(fromId)||addNode(fromId);var toNode=getNode(toId)||addNode(toId);var link=createLink(fromId,toId,data);links.push(link);addLinkToNode(fromNode,link);if(fromId!==toId){addLinkToNode(toNode,link)}recordLinkChange(link,"add");exitModification();return link}function createSingleLink(fromId,toId,data){var linkId=makeLinkId(fromId,toId);return new Link(fromId,toId,data,linkId)}function createUniqueLink(fromId,toId,data){var linkId=makeLinkId(fromId,toId);var isMultiEdge=multiEdges.hasOwnProperty(linkId);if(isMultiEdge||getLink(fromId,toId)){if(!isMultiEdge){multiEdges[linkId]=0}var suffix="@"+ ++multiEdges[linkId];linkId=makeLinkId(fromId+suffix,toId+suffix)}return new Link(fromId,toId,data,linkId)}function getLinks(nodeId){var node=getNode(nodeId);return node?node.links:null}function removeLink(link){if(!link){return false}var idx=indexOfElementInArray(link,links);if(idx<0){return false}enterModification();links.splice(idx,1);var fromNode=getNode(link.fromId);var toNode=getNode(link.toId);if(fromNode){idx=indexOfElementInArray(link,fromNode.links);if(idx>=0){fromNode.links.splice(idx,1)}}if(toNode){idx=indexOfElementInArray(link,toNode.links);if(idx>=0){toNode.links.splice(idx,1)}}recordLinkChange(link,"remove");exitModification();return true}function getLink(fromNodeId,toNodeId){var node=getNode(fromNodeId),i;if(!node||!node.links){return null}for(i=0;i<node.links.length;++i){var link=node.links[i];if(link.fromId===fromNodeId&&link.toId===toNodeId){return link}}return null}function clear(){enterModification();forEachNode(function(node){removeNode(node.id)});exitModification()}function forEachLink(callback){var i,length;if(typeof callback==="function"){for(i=0,length=links.length;i<length;++i){callback(links[i])}}}function forEachLinkedNode(nodeId,callback,oriented){var node=getNode(nodeId);if(node&&node.links&&typeof callback==="function"){if(oriented){return forEachOrientedLink(node.links,nodeId,callback)}else{return forEachNonOrientedLink(node.links,nodeId,callback)}}}function forEachNonOrientedLink(links,nodeId,callback){var quitFast;for(var i=0;i<links.length;++i){var link=links[i];var linkedNodeId=link.fromId===nodeId?link.toId:link.fromId;quitFast=callback(nodes.get(linkedNodeId),link);if(quitFast){return true}}}function forEachOrientedLink(links,nodeId,callback){var quitFast;for(var i=0;i<links.length;++i){var link=links[i];if(link.fromId===nodeId){quitFast=callback(nodes.get(link.toId),link);if(quitFast){return true}}}}function noop(){}function enterModificationReal(){suspendEvents+=1}function exitModificationReal(){suspendEvents-=1;if(suspendEvents===0&&changes.length>0){graphPart.fire("changed",changes);changes.length=0}}function forEachNode(callback){if(typeof callback!=="function"){throw new Error("Function is expected to iterate over graph nodes. You passed "+callback)}var valuesIterator=nodes.values();var nextValue=valuesIterator.next();while(!nextValue.done){if(callback(nextValue.value)){return true}nextValue=valuesIterator.next()}}}function indexOfElementInArray(element,array){if(!array)return-1;if(array.indexOf){return array.indexOf(element)}var len=array.length,i;for(i=0;i<len;i+=1){if(array[i]===element){return i}}return-1}function Node(id,data){this.id=id;this.links=null;this.data=data}function addLinkToNode(node,link){if(node.links){node.links.push(link)}else{node.links=[link]}}function Link(fromId,toId,data,id){this.fromId=fromId;this.toId=toId;this.data=data;this.id=id}function makeLinkId(fromId,toId){return fromId.toString()+"👉 "+toId.toString()}},{"ngraph.events":2}],2:[function(require,module,exports){module.exports=function(subject){validateSubject(subject);var eventsStorage=createEventsStorage(subject);subject.on=eventsStorage.on;subject.off=eventsStorage.off;subject.fire=eventsStorage.fire;return subject};function createEventsStorage(subject){var registeredEvents=Object.create(null);return{on:function(eventName,callback,ctx){if(typeof callback!=="function"){throw new Error("callback is expected to be a function")}var handlers=registeredEvents[eventName];if(!handlers){handlers=registeredEvents[eventName]=[]}handlers.push({callback:callback,ctx:ctx});return subject},off:function(eventName,callback){var wantToRemoveAll=typeof eventName==="undefined";if(wantToRemoveAll){registeredEvents=Object.create(null);return subject}if(registeredEvents[eventName]){var deleteAllCallbacksForEvent=typeof callback!=="function";if(deleteAllCallbacksForEvent){delete registeredEvents[eventName]}else{var callbacks=registeredEvents[eventName];for(var i=0;i<callbacks.length;++i){if(callbacks[i].callback===callback){callbacks.splice(i,1)}}}}return subject},fire:function(eventName){var callbacks=registeredEvents[eventName];if(!callbacks){return subject}var fireArguments;if(arguments.length>1){fireArguments=Array.prototype.splice.call(arguments,1)}for(var i=0;i<callbacks.length;++i){var callbackInfo=callbacks[i];callbackInfo.callback.apply(callbackInfo.ctx,fireArguments)}return subject}}}function validateSubject(subject){if(!subject){throw new Error("Eventify cannot use falsy object as events subject")}var reservedWords=["on","fire","off"];for(var i=0;i<reservedWords.length;++i){if(subject.hasOwnProperty(reservedWords[i])){throw new Error("Subject cannot be eventified, since it already has property '"+reservedWords[i]+"'")}}}},{}]},{},[1])(1)}); |
68
index.js
@@ -47,10 +47,13 @@ /** | ||
var nodes = typeof Object.create === 'function' ? Object.create(null) : {}, | ||
links = [], | ||
if (typeof Map !== 'function') { | ||
// TODO: Should we polyfill it ourselves? We don't use much operations there.. | ||
throw new Error('ngraph.graph requires `Map` to be defined. Please polyfill it before using ngraph'); | ||
} | ||
var nodes = new Map(); | ||
var links = [], | ||
// Hash of multi-edges. Used to track ids of edges between same nodes | ||
multiEdges = {}, | ||
nodesCount = 0, | ||
suspendEvents = 0, | ||
forEachNode = createNodeIterator(), | ||
createLink = options.multigraph ? createUniqueLink : createSingleLink, | ||
@@ -136,3 +139,3 @@ | ||
getNodesCount: function () { | ||
return nodesCount; | ||
return nodes.size; | ||
}, | ||
@@ -289,3 +292,2 @@ | ||
node = new Node(nodeId, data); | ||
nodesCount++; | ||
recordNodeChange(node, 'add'); | ||
@@ -297,3 +299,3 @@ } else { | ||
nodes[nodeId] = node; | ||
nodes.set(nodeId, node); | ||
@@ -305,3 +307,3 @@ exitModification(); | ||
function getNode(nodeId) { | ||
return nodes[nodeId]; | ||
return nodes.get(nodeId); | ||
} | ||
@@ -325,4 +327,3 @@ | ||
delete nodes[nodeId]; | ||
nodesCount--; | ||
nodes.delete(nodeId) | ||
@@ -476,3 +477,3 @@ recordNodeChange(node, 'remove'); | ||
quitFast = callback(nodes[linkedNodeId], link); | ||
quitFast = callback(nodes.get(linkedNodeId), link); | ||
if (quitFast) { | ||
@@ -489,3 +490,3 @@ return true; // Client does not need more iterations. Break now. | ||
if (link.fromId === nodeId) { | ||
quitFast = callback(nodes[link.toId], link); | ||
quitFast = callback(nodes.get(link.toId), link) | ||
if (quitFast) { | ||
@@ -515,34 +516,16 @@ return true; // Client does not need more iterations. Break now. | ||
function createNodeIterator() { | ||
// Object.keys iterator is 1.3x faster than `for in` loop. | ||
// See `https://github.com/anvaka/ngraph.graph/tree/bench-for-in-vs-obj-keys` | ||
// branch for perf test | ||
return Object.keys ? objectKeysIterator : forInIterator; | ||
} | ||
function objectKeysIterator(callback) { | ||
function forEachNode(callback) { | ||
if (typeof callback !== 'function') { | ||
return; | ||
throw new Error('Function is expected to iterate over graph nodes. You passed ' + callback); | ||
} | ||
var keys = Object.keys(nodes); | ||
for (var i = 0; i < keys.length; ++i) { | ||
if (callback(nodes[keys[i]])) { | ||
var valuesIterator = nodes.values(); | ||
var nextValue = valuesIterator.next(); | ||
while (!nextValue.done) { | ||
if (callback(nextValue.value)) { | ||
return true; // client doesn't want to proceed. Return. | ||
} | ||
nextValue = valuesIterator.next(); | ||
} | ||
} | ||
function forInIterator(callback) { | ||
if (typeof callback !== 'function') { | ||
return; | ||
} | ||
var node; | ||
for (node in nodes) { | ||
if (callback(nodes[node])) { | ||
return true; // client doesn't want to proceed. Return. | ||
} | ||
} | ||
} | ||
} | ||
@@ -597,15 +580,4 @@ | ||
function hashCode(str) { | ||
var hash = 0, i, chr, len; | ||
if (str.length == 0) return hash; | ||
for (i = 0, len = str.length; i < len; i++) { | ||
chr = str.charCodeAt(i); | ||
hash = ((hash << 5) - hash) + chr; | ||
hash |= 0; // Convert to 32bit integer | ||
} | ||
return hash; | ||
} | ||
function makeLinkId(fromId, toId) { | ||
return fromId.toString() + '👉 ' + toId.toString(); | ||
} |
{ | ||
"name": "ngraph.graph", | ||
"version": "18.0.3", | ||
"version": "19.0.0", | ||
"description": "graph data structure", | ||
@@ -32,4 +32,6 @@ "main": "index.js", | ||
"devDependencies": { | ||
"benchmark": "^2.1.4", | ||
"browserify": "^16.4.0", | ||
"tap": "^14.6.1", | ||
"ngraph.random": "^1.0.0", | ||
"tap": "^14.9.2", | ||
"uglify-js": "^3.6.0" | ||
@@ -36,0 +38,0 @@ }, |
@@ -1,15 +0,20 @@ | ||
Node v7.2.1 | ||
Node v12.4.0 | ||
> node perf/edge-iteration.js | ||
Edge iteration x 524 ops/sec ±2.04% (82 runs sampled) | ||
Edge iteration for multigraph x 464 ops/sec ±2.17% (84 runs sampled) | ||
Edge iteration x 626 ops/sec ±1.36% (86 runs sampled) | ||
Edge iteration for multigraph x 568 ops/sec ±0.97% (87 runs sampled) | ||
» node perf/graph-construction.js | ||
Adding 5,000 edges x 201 ops/sec ±4.84% (59 runs sampled) | ||
Adding 5,000 multigraph edges x 172 ops/sec ±4.59% (69 runs sampled) | ||
Adding 5,000 random edges x 135 ops/sec ±3.55% (70 runs sampled) | ||
Adding 5,000 random edges to multigraph x 115 ops/sec ±3.74% (73 runs sampled) | ||
Adding 5,000 random edges and randomly removing them x 7.44 ops/sec ±3.22% (23 runs sampled) | ||
Adding 5,000 random edges to multigraph and randomly removing them x 5.62 ops/sec ±4.80% (18 runs sampled) | ||
Removing all edges one by one from 5k graph x 108 ops/sec ±3.61% (68 runs sampled) | ||
Removing all edges one by one from 5k multigraph graph x 93.03 ops/sec ±2.93% (68 runs sampled) | ||
Adding 5,000 edges x 580 ops/sec ±1.40% (86 runs sampled) | ||
Adding 5,000 multigraph edges x 432 ops/sec ±1.08% (82 runs sampled) | ||
Adding 5,000 random edges x 219 ops/sec ±0.92% (81 runs sampled) | ||
Adding 5,000 random edges to multigraph x 179 ops/sec ±0.93% (78 runs sampled) | ||
Adding 5,000 random edges and randomly removing them x 7.83 ops/sec ±4.33% (24 runs sampled) | ||
Adding 5,000 random edges to multigraph and randomly removing them x 5.97 ops/sec ±4.07% (20 runs sampled) | ||
Removing all edges one by one from 5k graph x 126 ops/sec ±1.20% (76 runs sampled) | ||
Removing all edges one by one from 5k multigraph graph x 97.78 ops/sec ±4.15% (69 runs sampled) | ||
» node perf/node-iteration.js | ||
graphWithOutMap x 572 ops/sec ±3.64% (71 runs sampled) | ||
graphWithMap x 5,744 ops/sec ±6.48% (69 runs sampled) | ||
Fastest is graphWithMap |
@@ -90,3 +90,3 @@ var test = require('tap').test, | ||
t.equals(graph.getLinksCount(), 1, 'one link'); | ||
t.equal(iterated, 2, 'has two nodes'); | ||
t.equals(iterated, 2, 'has two nodes'); | ||
t.end(); | ||
@@ -93,0 +93,0 @@ }); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
16
75006
5
1705