| 73 | this.outputPath = this.currentDirectory; |
| 74 | } |
| 75 | build(length, keys, values, G, H) { |
| 76 | // adapted from https://github.com/mixu/perfect |
| 77 | var buckets = []; |
| 78 | var modulo, bucket; |
| 79 | keys.forEach(key => { |
| 80 | modulo = this.hash(0, key) % length; |
| 81 | bucket = buckets[modulo]; |
| 82 | if (bucket) |
| 83 | bucket.push(key); |
| 84 | else |
| 85 | bucket = [ key ]; |
| 86 | buckets[modulo] = bucket; |
| 87 | }); |
| 88 | buckets.sort((a, b) => b ? (a ? b.length - a.length : b.length) : (a ? 0 - a.length : 0)); |
| 89 | for (modulo = 0; modulo < length; modulo++) { |
| 90 | bucket = buckets[modulo]; |
| 91 | if (!bucket || (bucket.length <= 1)) |
| 92 | break; |
| 93 | var c = bucket.length, i = 0; |
| 94 | var d = 1, slots = [], slot, used = {}; |
| 95 | while (i < c) { |
| 96 | slot = this.hash(d, bucket[i]) % length; |
| 97 | if ((H[slot] !== undefined) || used[slot]) { |
| 98 | d++; |
| 99 | i = 0; |
| 100 | slots = []; |
| 101 | used = {}; |
| 102 | } |
| 103 | else { |
| 104 | i++; |
| 105 | slots.push(slot); |
| 106 | used[slot] = true; |
| 107 | } |
| 108 | } |
| 109 | G[this.hash(0, bucket[0]) % length] = d; |
| 110 | bucket.forEach((key, index) => { |
| 111 | H[slots[index]] = values[key]; |
| 112 | }); |
| 113 | } |
| 114 | var slots = []; |
| 115 | H.forEach((value, index) => { |
| 116 | if (value === undefined) |
| 117 | slots.push(index); |
| 118 | }); |
| 119 | for(; modulo < length; modulo++ ) { |
| 120 | bucket = buckets[modulo]; |
| 121 | if (!bucket || bucket.length == 0) |
| 122 | break; |
| 123 | var key = bucket[0]; |
| 124 | var slot = slots.pop(); |
| 125 | G[this.hash(0, key) % length] = 0 - slot - 1; |
| 126 | H[slot] = values[key]; |
| 127 | } |
| 128 | } |
| 129 | run() { |
| 130 | var locals = this.inputPaths.map(path => { |
| 131 | var parts = this.splitPath(path); |