Skip to content

Commit

Permalink
os: improve networkInterfaces performance
Browse files Browse the repository at this point in the history
This algorithm uses less data transformations and is therefore
significantly faster than the one before.

PR-URL: nodejs#22359
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Tiancheng "Timothy" Gu <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
  • Loading branch information
BridgeAR committed Aug 20, 2018
1 parent 104492b commit 9bcb744
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 86 deletions.
41 changes: 0 additions & 41 deletions lib/internal/os.js

This file was deleted.

67 changes: 57 additions & 10 deletions lib/os.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
const { pushValToArrayMax, safeGetenv } = process.binding('util');
const constants = process.binding('constants').os;
const { deprecate } = require('internal/util');
const { getCIDRSuffix } = require('internal/os');
const isWindows = process.platform === 'win32';

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

// Returns the number of ones in the binary representation of the decimal
// number.
function countBinaryOnes(n) {
let count = 0;
// Remove one "1" bit from n until n is the power of 2. This iterates k times
// while k is the number of "1" in the binary representation.
// For more check https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
while (n !== 0) {
n = n & (n - 1);
count++;
}
return count;
}

function getCIDR({ address, netmask, family }) {
let ones = 0;
let split = '.';
let range = 10;
let groupLength = 8;
let hasZeros = false;

if (family === 'IPv6') {
split = ':';
range = 16;
groupLength = 16;
}

const parts = netmask.split(split);
for (var i = 0; i < parts.length; i++) {
if (parts[i] !== '') {
const binary = parseInt(parts[i], range);
const tmp = countBinaryOnes(binary);
ones += tmp;
if (hasZeros) {
if (tmp !== 0) {
return null;
}
} else if (tmp !== groupLength) {
if ((binary & 1) !== 0) {
return null;
}
hasZeros = true;
}
}
}

return `${address}/${ones}`;
}

function networkInterfaces() {
const interfaceAddresses = getInterfaceAddresses();

return Object.entries(interfaceAddresses).reduce((acc, [key, val]) => {
acc[key] = val.map((v) => {
const protocol = v.family.toLowerCase();
const suffix = getCIDRSuffix(v.netmask, protocol);
const cidr = suffix ? `${v.address}/${suffix}` : null;
const keys = Object.keys(interfaceAddresses);
for (var i = 0; i < keys.length; i++) {
const arr = interfaceAddresses[keys[i]];
for (var j = 0; j < arr.length; j++) {
arr[j].cidr = getCIDR(arr[j]);
}
}

return Object.assign({}, v, { cidr });
});
return acc;
}, {});
return interfaceAddresses;
}

module.exports = {
Expand Down
1 change: 0 additions & 1 deletion node.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@
'lib/internal/modules/esm/translators.js',
'lib/internal/safe_globals.js',
'lib/internal/net.js',
'lib/internal/os.js',
'lib/internal/priority_queue.js',
'lib/internal/process/esm_loader.js',
'lib/internal/process/main_thread_only.js',
Expand Down
32 changes: 0 additions & 32 deletions test/parallel/test-internal-os.js

This file was deleted.

4 changes: 2 additions & 2 deletions test/parallel/test-os.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ switch (platform) {
const expected = [{
address: '127.0.0.1',
netmask: '255.0.0.0',
mac: '00:00:00:00:00:00',
family: 'IPv4',
mac: '00:00:00:00:00:00',
internal: true,
cidr: '127.0.0.1/8'
}];
Expand All @@ -146,8 +146,8 @@ switch (platform) {
const expected = [{
address: '127.0.0.1',
netmask: '255.0.0.0',
mac: '00:00:00:00:00:00',
family: 'IPv4',
mac: '00:00:00:00:00:00',
internal: true,
cidr: '127.0.0.1/8'
}];
Expand Down

0 comments on commit 9bcb744

Please sign in to comment.