Skip to content

Commit 3de2020

Browse files
committed
refactoring + skip unneeded iterations for duplicate keys
1 parent d2f13c8 commit 3de2020

1 file changed

Lines changed: 52 additions & 28 deletions

File tree

src/crons/websocket/room.key.generator.ts

Lines changed: 52 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,54 +9,78 @@ export class RoomKeyGenerator {
99
dtoClass: Function,
1010
): string[] {
1111
const allowedKeys = this.getKeys(dtoClass);
12+
const activeFilters = this.collectActiveFilters(allowedKeys, data);
1213

13-
// extract only key-value pairs that exist in the data and are non-null
14+
if (activeFilters.length === 0) {
15+
return [];
16+
}
17+
18+
return this.buildRoomKeys(prefix, activeFilters);
19+
}
20+
21+
private static collectActiveFilters(allowedKeys: string[], data: Record<string, any>) {
1422
const activeFilters: { key: string; value: any }[] = [];
1523

1624
for (const key of allowedKeys) {
1725
if (key === 'token') {
18-
const value = data['value'];
19-
if (value != null && value !== '' && value !== '0') {
20-
activeFilters.push({ key: 'token', value: 'EGLD' });
21-
}
22-
const transfers = data?.action?.arguments?.transfers;
23-
if (Array.isArray(transfers)) {
24-
for (const transfer of transfers) {
25-
if (transfer.token) {
26-
activeFilters.push({ key: 'token', value: transfer.token });
27-
}
28-
}
29-
}
30-
} else {
31-
const value = data[key];
32-
// Ignore null, undefined, and empty strings
33-
if (value !== undefined && value !== null && value !== '') {
34-
activeFilters.push({ key, value });
35-
}
26+
this.addTokenFilters(activeFilters, data);
27+
continue;
28+
}
29+
30+
const value = data[key];
31+
if (this.isValidFilterValue(value)) {
32+
activeFilters.push({ key, value });
3633
}
3734
}
3835

39-
if (activeFilters.length === 0) {
40-
return [];
36+
return activeFilters;
37+
}
38+
39+
private static addTokenFilters(activeFilters: { key: string; value: any }[], data: Record<string, any>) {
40+
const value = data['value'];
41+
if (this.isValidFilterValue(value) && value !== '0') {
42+
activeFilters.push({ key: 'token', value: 'EGLD' });
43+
}
44+
45+
const transfers = data?.action?.arguments?.transfers;
46+
if (!Array.isArray(transfers)) {
47+
return;
4148
}
4249

50+
for (const transfer of transfers) {
51+
if (this.isValidFilterValue(transfer?.token)) {
52+
activeFilters.push({ key: 'token', value: transfer.token });
53+
}
54+
}
55+
}
56+
57+
private static isValidFilterValue(value: any) {
58+
return value !== undefined && value !== null && value !== '';
59+
}
60+
61+
private static buildRoomKeys(prefix: string, activeFilters: { key: string; value: any }[]) {
4362
const rooms: string[] = [];
4463
const subsetCount = 1 << activeFilters.length; // 2^N combinations
4564

46-
// Generate combinatorics
4765
// Start from 1 to ignore the empty set
48-
for (let i = 1; i < subsetCount; i++) {
66+
for (let mask = 1; mask < subsetCount; mask++) {
4967
const currentSubset: Record<string, any> = {};
68+
let skipIteration = false;
5069

51-
for (let j = 0; j < activeFilters.length; j++) {
70+
for (let bit = 0; bit < activeFilters.length; bit++) {
5271
// Check the bit to decide whether to include the element in the subset
53-
if ((i & (1 << j)) > 0) {
54-
const item = activeFilters[j];
72+
if ((mask & (1 << bit)) > 0) {
73+
if (currentSubset.hasOwnProperty(activeFilters[bit].key)) {
74+
skipIteration = true;
75+
continue; // Skip duplicate keys
76+
}
77+
const item = activeFilters[bit];
5578
currentSubset[item.key] = item.value;
5679
}
5780
}
58-
59-
rooms.push(`${prefix}${this.deterministicStringify(currentSubset)}`);
81+
if (!skipIteration) {
82+
rooms.push(`${prefix}${this.deterministicStringify(currentSubset)}`);
83+
}
6084
}
6185

6286
return rooms;

0 commit comments

Comments
 (0)