forked from postalsys/emailengine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
scan.js
122 lines (101 loc) · 3.36 KB
/
scan.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
/* eslint no-console: 0, id-length: 0, no-plusplus: 0 */
'use strict';
const config = require('wild-config');
const Redis = require('ioredis');
const redisUrl = require('./lib/redis-url');
const packageData = require('./package.json');
const { threadId } = require('worker_threads');
config.dbs = config.dbs || {
redis: 'redis://127.0.0.1:6379/8'
};
const redisConf = process.env.EENGINE_REDIS || config.dbs.redis;
const REDIS_CONF = Object.assign(
{
// some defaults
showFriendlyErrorStack: true,
connectionName: `${packageData.name}@${packageData.version}[${process.pid}${threadId ? `:${threadId}` : ''}][scan]`
},
typeof redisConf === 'string' ? redisUrl(redisConf) : redisConf || {}
);
const redis = new Redis(REDIS_CONF);
const MAX_PAGE = 1000;
let keymap = new Map();
let countKeys = 0;
const scanKeys = () => {
console.log('KEY,COUNT');
return new Promise((resolve, reject) => {
const stream = redis.scanStream({
count: MAX_PAGE
});
let reading = false;
let finished = false;
const countKey = str => {
if (str.match(/^bull:/)) {
str = str.replace(/:[^:]+$/, ':*');
} else if (/^ia[mlhrq]:/.test(str)) {
str = str.replace(/:[^:]+$/, ':*');
} else {
str = str
.replace(/\b[a-f0-9]{16,}\b/g, m => `hash(${m.length})`)
.replace(/\b[0-9]{6,}\b/g, m => `num(${m.length})`)
.replace(/\b[a-f0-9]{8,}\b/g, m => `hash(${m.length})`)
.replace(/[a-z0-9._-]+@[a-z0-9.-]+/g, () => 'email()')
.replace(/\d{4}\/\d{2}\/\d{2}/g, () => `date(yyyy/mm/dd)`);
}
if (keymap.has(str)) {
keymap.set(str, keymap.get(str) + 1);
} else {
keymap.set(str, 1);
}
};
const readFromStream = async () => {
let resultKeys;
while ((resultKeys = stream.read()) !== null) {
for (let i = 0; i < resultKeys.length; i++) {
countKey(resultKeys[i]);
countKeys++;
}
}
};
const finish = async () => {
for (let [key, val] of keymap) {
console.log(`"${key.replace(/"/g, '""')}",${val}`);
}
console.error(`Checked ${countKeys} keys`);
resolve();
};
stream.on('readable', () => {
if (!reading) {
reading = true;
readFromStream().then(() => {
reading = false;
if (finished) {
finish();
}
});
}
});
stream.on('end', () => {
finished = true;
if (reading) {
return;
}
finish();
});
stream.on('error', err => {
reject(err);
});
});
};
let start = Date.now();
let interval = setInterval(() => {
console.error(`Key size: ${keymap.size}; Counted: ${countKeys}`);
}, 10 * 1000);
scanKeys()
.then(() => console.error('done'))
.catch(err => console.error(err))
.finally(() => {
clearInterval(interval);
console.error(`Time: ${Date.now() - start}ms`);
process.exit();
});