Skip to content

Commit 3b44053

Browse files
BridgeARtargos
authored andcommitted
os: improve networkInterfaces performance
This algorithm uses less data transformations and is therefore significantly faster than the one before. PR-URL: #22359 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Tiancheng "Timothy" Gu <[email protected]> Reviewed-By: Luigi Pinca <[email protected]>
1 parent 8f760c2 commit 3b44053

File tree

5 files changed

+59
-86
lines changed

5 files changed

+59
-86
lines changed

lib/internal/os.js

-41
This file was deleted.

lib/os.js

+57-10
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
const { pushValToArrayMax, safeGetenv } = process.binding('util');
2525
const constants = process.binding('constants').os;
2626
const { deprecate } = require('internal/util');
27-
const { getCIDRSuffix } = require('internal/os');
2827
const isWindows = process.platform === 'win32';
2928

3029
const { ERR_SYSTEM_ERROR } = require('internal/errors');
@@ -144,19 +143,67 @@ function endianness() {
144143
}
145144
endianness[Symbol.toPrimitive] = () => kEndianness;
146145

146+
// Returns the number of ones in the binary representation of the decimal
147+
// number.
148+
function countBinaryOnes(n) {
149+
let count = 0;
150+
// Remove one "1" bit from n until n is the power of 2. This iterates k times
151+
// while k is the number of "1" in the binary representation.
152+
// For more check https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
153+
while (n !== 0) {
154+
n = n & (n - 1);
155+
count++;
156+
}
157+
return count;
158+
}
159+
160+
function getCIDR({ address, netmask, family }) {
161+
let ones = 0;
162+
let split = '.';
163+
let range = 10;
164+
let groupLength = 8;
165+
let hasZeros = false;
166+
167+
if (family === 'IPv6') {
168+
split = ':';
169+
range = 16;
170+
groupLength = 16;
171+
}
172+
173+
const parts = netmask.split(split);
174+
for (var i = 0; i < parts.length; i++) {
175+
if (parts[i] !== '') {
176+
const binary = parseInt(parts[i], range);
177+
const tmp = countBinaryOnes(binary);
178+
ones += tmp;
179+
if (hasZeros) {
180+
if (tmp !== 0) {
181+
return null;
182+
}
183+
} else if (tmp !== groupLength) {
184+
if ((binary & 1) !== 0) {
185+
return null;
186+
}
187+
hasZeros = true;
188+
}
189+
}
190+
}
191+
192+
return `${address}/${ones}`;
193+
}
194+
147195
function networkInterfaces() {
148196
const interfaceAddresses = getInterfaceAddresses();
149197

150-
return Object.entries(interfaceAddresses).reduce((acc, [key, val]) => {
151-
acc[key] = val.map((v) => {
152-
const protocol = v.family.toLowerCase();
153-
const suffix = getCIDRSuffix(v.netmask, protocol);
154-
const cidr = suffix ? `${v.address}/${suffix}` : null;
198+
const keys = Object.keys(interfaceAddresses);
199+
for (var i = 0; i < keys.length; i++) {
200+
const arr = interfaceAddresses[keys[i]];
201+
for (var j = 0; j < arr.length; j++) {
202+
arr[j].cidr = getCIDR(arr[j]);
203+
}
204+
}
155205

156-
return Object.assign({}, v, { cidr });
157-
});
158-
return acc;
159-
}, {});
206+
return interfaceAddresses;
160207
}
161208

162209
module.exports = {

node.gyp

-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,6 @@
132132
'lib/internal/modules/esm/translators.js',
133133
'lib/internal/safe_globals.js',
134134
'lib/internal/net.js',
135-
'lib/internal/os.js',
136135
'lib/internal/process/esm_loader.js',
137136
'lib/internal/process/main_thread_only.js',
138137
'lib/internal/process/next_tick.js',

test/parallel/test-internal-os.js

-32
This file was deleted.

test/parallel/test-os.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,8 @@ switch (platform) {
130130
const expected = [{
131131
address: '127.0.0.1',
132132
netmask: '255.0.0.0',
133-
mac: '00:00:00:00:00:00',
134133
family: 'IPv4',
134+
mac: '00:00:00:00:00:00',
135135
internal: true,
136136
cidr: '127.0.0.1/8'
137137
}];
@@ -146,8 +146,8 @@ switch (platform) {
146146
const expected = [{
147147
address: '127.0.0.1',
148148
netmask: '255.0.0.0',
149-
mac: '00:00:00:00:00:00',
150149
family: 'IPv4',
150+
mac: '00:00:00:00:00:00',
151151
internal: true,
152152
cidr: '127.0.0.1/8'
153153
}];

0 commit comments

Comments
 (0)