-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathflickr-fetcher.js
92 lines (80 loc) · 2.42 KB
/
flickr-fetcher.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
var FlickrFetcher;
FlickrFetcher = {
installerOrder: function(packages){
if(!packages){
return '';
}
let packageGraph = new Map();
// If one package has no dependency, its indegree index is 0.
// If one package has one dependency, its indegree index is 1.
let indegrees = new Map();
let queue = [];
let count = 0, installOrder = '';
// Build the graph.
packages.forEach(pair => {
let pairArr = pair.split(': ');
let dependency = pairArr[1];
let package = pairArr[0];
// If one package has one dependency, its indegree index is 1.
if(dependency === ''){
indegrees.set(package, 0);
}
else{ // Map the dependency package to the packages which requires the dependency package.
if(!packageGraph.has(dependency)){
packageGraph.set(dependency, []);
}
packageGraph.get(dependency).push(package);
if(!indegrees.has(package)){
indegrees.set(package, 1);
}
else{
indegrees.set(package, indegrees.get(package) + 1);
}
}
});
// Put the package with indegree index 0 to the queue
for(let [package, indegree] of indegrees){
if(indegree === 0){
queue.push(package);
count++;
installOrder += package + ', ';
}
}
// For the package in the queue, if there is package which requires it,
// decrement the indegree of the requring package. If the requiring package
// has indegree index 0, put it to the queue. Recurisively go through the
// package in the queue, until the queue is empty.
// During the interation process, count the package which has indegree 0;
while(queue.length > 0){
let size = queue.length;
while(size > 0){
let installed = queue.shift();
if(packageGraph.has(installed)){
packageGraph.get(installed).forEach( toInstall => {
indegrees.set(toInstall, indegrees.get(toInstall) - 1);
if(indegrees.get(toInstall) === 0){
count++;
queue.push(toInstall);
installOrder += toInstall + ', ';
}
} );
}
size--;
}
}
// If all of the packages have been iterated, there is no cycles.
try{
if(count === indegrees.size){ // No cycle
return installOrder.substring(0, installOrder.length - 2);
}
else{
// throw 'Dependencies specificatoin contains cycle.';
throw new TypeError('Dependencies specificatoin contains cycle.');
}
}
catch(e){
console.log('Dependencies specificatoin contains cycle.');
}
}
};
module.exports = FlickrFetcher;