-
Notifications
You must be signed in to change notification settings - Fork 48
/
Copy pathexerex-userhash-solve02-faster.js
104 lines (77 loc) · 2.69 KB
/
exerex-userhash-solve02-faster.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
/*
USERNAME HASH PROBLEM
Although the problem is solved in previous solution, the calculation speed keeps too slow.
Analyze the Hash Task and you realize that
this task can be divided into multiple individual sub tasks.
Each sub task is corresponding to hashing one chunk.
Hence, multithreading makes sense: Each thread does each sub task in parallel.
*/
import * as mylib from './mylib.js';
import { isMainThread, workerData, parentPort } from 'worker_threads';
import express from 'express';
import { getHash, splitStrInToChunks } from './exerex-userhash-util.js';
//---------------------------------------------
// WORKER THREAD SECTION
//---------------------------------------------
export const workerFunc = () => {
try {
const [idx, chunk] = workerData;
const chunkHash = getHash(2**21, chunk);
parentPort.postMessage([idx, chunkHash]);
} catch (error) {
console.error(error);
}
};
//---------------------------------------------
// MAIN THREAD SECTION
//---------------------------------------------
const getSuperHashByMain = async (plainText) => {
const numChunks = 8; // It is also the number of threads
const lstChunks = splitStrInToChunks(numChunks, plainText);
const lstHashes = new Array(numChunks);
const lstWorkerProm = [];
for (let i = 0; i < numChunks; ++i) {
const chunk = lstChunks[i];
const [worker, prom] = mylib.createThread(new URL(import.meta.url), [i, chunk]);
worker.on('message', ([idx, chunkHash]) => lstHashes[idx] = chunkHash);
lstWorkerProm.push(prom);
}
await Promise.all(lstWorkerProm);
const finalHash = getHash(1, lstHashes.join(''));
return finalHash;
};
const mainFunc = () => {
const PORT = 8081;
const app = express();
const userNameHistory = [];
app.get('/history', async (req, res) => {
const html = userNameHistory.join('<br/>') || '<Empty history>';
res.status(200).send(html).end();
});
app.get('/', async (req, res) => {
const userName = req.query.name;
if (!userName) {
res.status(400).end();
return;
}
userNameHistory.push(userName);
const tpStart = process.hrtime();
// GET USERNAME HASH
const userNameHash = await getSuperHashByMain(userName);
const timeElapsed = mylib.hrtimeToNumber(process.hrtime(tpStart));
console.log(`userName = ${userName}; Time elapsed = ${timeElapsed}`);
const html = userName + '<br/>' + userNameHash;
res.status(200).setHeader('Content-Type', 'text/html').send(html).end();
});
console.log('Server is listening on port', PORT);
const server = app.listen(PORT);
};
if (isMainThread) {
try {
mainFunc();
} catch (error) {
console.error(error);
}
} else {
workerFunc();
}