Skip to content

Commit 3a1077a

Browse files
authored
Merge pull request #152 from snyk/fix/skip-duplicated-edge-recording
fix: stop duplicate recording of Edge objects
2 parents b58bd7a + 20be9f6 commit 3a1077a

1 file changed

Lines changed: 24 additions & 41 deletions

File tree

src/graphlib/graph.ts

Lines changed: 24 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,7 @@ export class Graph {
5757
_parent;
5858
_children;
5959

60-
_in: Record<NodeId, Record<EdgeId, Edge>>;
6160
_preds: Record<NodeId, AdjacencyCounts>;
62-
_out: Record<NodeId, Record<EdgeId, Edge>>;
6361
_sucs: Record<NodeId, AdjacencyCounts>;
6462
_edgeObjs: Record<EdgeId, Edge>;
6563
_edgeLabels: Record<EdgeId, unknown>;
@@ -90,15 +88,9 @@ export class Graph {
9088
this._children[GRAPH_NODE] = {};
9189
}
9290

93-
// v -> edgeObj
94-
this._in = {};
95-
9691
// u -> v -> Number
9792
this._preds = {};
9893

99-
// v -> edgeObj
100-
this._out = {};
101-
10294
// v -> w -> Number
10395
this._sucs = {};
10496

@@ -153,14 +145,14 @@ export class Graph {
153145
sources(): NodeId[] {
154146
const self = this;
155147
return _filter(this.nodes(), (v: NodeId) => {
156-
return isEmpty(self._in[v]);
148+
return isEmpty(self._preds[v]);
157149
});
158150
}
159151

160152
sinks(): NodeId[] {
161153
const self = this;
162154
return _filter(this.nodes(), (v: NodeId) => {
163-
return isEmpty(self._out[v]);
155+
return isEmpty(self._sucs[v]);
164156
});
165157
}
166158

@@ -191,9 +183,7 @@ export class Graph {
191183
this._children[v] = {};
192184
this._children[GRAPH_NODE][v] = true;
193185
}
194-
this._in[v] = {};
195186
this._preds[v] = {};
196-
this._out[v] = {};
197187
this._sucs[v] = {};
198188
return this;
199189
}
@@ -209,9 +199,13 @@ export class Graph {
209199
removeNode(v: NodeId): Graph {
210200
const self = this;
211201
if (v in this._nodes) {
212-
const removeEdge = (e: EdgeId) => {
213-
self.removeEdge(self._edgeObjs[e]);
214-
};
202+
const incidentEdges: Edge[] = [];
203+
for (const e in this._edgeObjs) {
204+
const edge = this._edgeObjs[e];
205+
if (edge.v === v || edge.w === v) {
206+
incidentEdges.push(edge);
207+
}
208+
}
215209
delete this._nodes[v];
216210
if (this._isCompound) {
217211
this._removeFromParentsChildList(v);
@@ -221,11 +215,10 @@ export class Graph {
221215
});
222216
delete this._children[v];
223217
}
224-
each(Object.keys(this._in[v]), removeEdge);
225-
delete this._in[v];
218+
for (const edge of incidentEdges) {
219+
this.removeEdge(edge);
220+
}
226221
delete this._preds[v];
227-
each(Object.keys(this._out[v]), removeEdge);
228-
delete this._out[v];
229222
delete this._sucs[v];
230223
}
231224
return this;
@@ -465,8 +458,6 @@ export class Graph {
465458
this._edgeObjs[e] = edgeObj;
466459
incrementOrInitEntry(this._preds[w], v);
467460
incrementOrInitEntry(this._sucs[v], w);
468-
this._in[w][e] = edgeObj;
469-
this._out[v][e] = edgeObj;
470461
return this;
471462
}
472463

@@ -499,38 +490,30 @@ export class Graph {
499490
delete this._edgeObjs[e];
500491
decrementOrRemoveEntry(this._preds[w], v);
501492
decrementOrRemoveEntry(this._sucs[v], w);
502-
delete this._in[w][e];
503-
delete this._out[v][e];
504493
}
505494
return this;
506495
}
507496

508497
inEdges(v: NodeId, u?: NodeId): Edge[] {
509-
const inV = this._in[v];
510-
if (inV) {
511-
const edges = values(inV);
512-
if (!u) {
513-
return edges;
498+
const edges: Edge[] = [];
499+
for (const e in this._edgeObjs) {
500+
const edge = this._edgeObjs[e];
501+
if (edge.w === v && (!u || edge.v === u)) {
502+
edges.push(edge);
514503
}
515-
return _filter(edges, function (edge) {
516-
return edge.v === u;
517-
});
518504
}
519-
return [];
505+
return edges;
520506
}
521507

522508
outEdges(v: NodeId, w?: NodeId): Edge[] {
523-
const outV = this._out[v];
524-
if (outV) {
525-
const edges = values(outV);
526-
if (!w) {
527-
return edges;
509+
const edges: Edge[] = [];
510+
for (const e in this._edgeObjs) {
511+
const edge = this._edgeObjs[e];
512+
if (edge.v === v && (!w || edge.w === w)) {
513+
edges.push(edge);
528514
}
529-
return _filter(edges, function (edge) {
530-
return edge.w === w;
531-
});
532515
}
533-
return [];
516+
return edges;
534517
}
535518

536519
nodeEdges(v: NodeId, w?: NodeId): Edge[] {

0 commit comments

Comments
 (0)