forked from graphmalizer/graphmalizer-core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
test-permutation.js
129 lines (107 loc) · 3.12 KB
/
test-permutation.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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// reads requests from stdin and tries out all permutations ensuring that we get the same graph
var R = require('ramda')
var hashOf = require('./utils/hashOf')
var _ = require('highland')
var conf = require('./utils/config')
var Queries = require('./core/queries')
var batchCommit = _.wrapCallback(require('./utils/neo4batch'))
var Combinatorics = require('js-combinatorics')
function mkQuery (s) {
return [{statement: s, parameters: {}}]
}
// delete everything
var clearDB = mkQuery(
'MATCH n OPTIONAL MATCH n-[e]-() DELETE e, n RETURN DISTINCT true;'
)
// get all node, edge id's
var enumerateDB = mkQuery(
'MATCH (n) OPTIONAL MATCH (n)-[e]-()' +
'RETURN collect(DISTINCT n.id), collect(DISTINCT e.id)'
)
_(process.stdin)
.splitBy('\n')
.filter(function (s) {
return s !== ''
})
.map(function (s) {
// diff-ish
if (/^[+-]/.test(s)) {
var o = JSON.parse(s.slice(1))
o.operation = (s[0] === '+' ? 'add' : 'remove')
return o
}
// regular obj
return JSON.parse(s)
})
.map(function (o) {
// default operation is add
o.operation = o.operation || 'add'
// sourceId is alias for dataset
o.dataset = o.sourceId || o.dataset
// s, t, from, to alias for source/target
o.source = o.from || o.source || o.s
o.target = o.to || o.target || o.t
// ensure data field
o.data = o.data || {}
// if we have a name, copy into data field
o.data.name = o.name
// lookup structure (based on type)
o.structure = Object.keys(conf.types[o.type])[0]
// strip namespace
o.type = o.type.replace(/(^hg:)|[-_,;.]/g, '')
return o
})
.collect()
.consume(function (err, x, push, next) {
if (err) {
// pass errors along the stream and consume next value
push(err)
next()
} else if (x === _.nil) {
// pass nil (end event) along the stream
push(null, x)
} else {
// first do all add, then all removes
var things = R.groupBy(R.prop('operation'), x)
// create all permutations of adds and removes separately
var perms = R.mapObj(function (xs) {
return Combinatorics.permutation(xs).toArray()
}, things)
// take product [adds] ++ [removes]
var cp = Combinatorics.cartesianProduct(
perms['add'] || [],
perms['remove'] || []
).toArray()
// for each combination, push out concatenated list again
cp.forEach(function (c) {
push(null, R.concat(c[0], c[1]))
})
next()
}
})
.map(function (o) {
// make query
return o.map(function (o) {
return Queries.mkQuery(o.structure, o.operation, o)
})
})
.map(function (permutation) {
// clear, query, enumerate
return clearDB
.concat(permutation)
.concat(enumerateDB)
})
.map(batchCommit)
.series()
.flatten()
.each(function (data) {
// find the rows
var d = R.last(data.result.results).data
// for each row, output the first and second column
d = R.flatten(d.map(function (dd) {
return [dd.row[0], dd.row[1]]
}))
// hash sorted id's
var ghash = hashOf(d.sort())
console.log('GHASH =>', ghash)
})