diff options
author | Ruben Bridgewater <ruben@bridgewater.de> | 2018-08-16 14:31:04 +0200 |
---|---|---|
committer | Ruben Bridgewater <ruben@bridgewater.de> | 2018-08-20 16:10:20 +0200 |
commit | 9bcb744ee58f7f53f0a9b77f6ee36a4477ab43b4 (patch) | |
tree | 6fc7fba2f604779b4c57b80135c5b305613693a1 /lib/os.js | |
parent | 104492bd8321ba1ba3309f60b108c8d80f046e4a (diff) | |
download | android-node-v8-9bcb744ee58f7f53f0a9b77f6ee36a4477ab43b4.tar.gz android-node-v8-9bcb744ee58f7f53f0a9b77f6ee36a4477ab43b4.tar.bz2 android-node-v8-9bcb744ee58f7f53f0a9b77f6ee36a4477ab43b4.zip |
os: improve networkInterfaces performance
This algorithm uses less data transformations and is therefore
significantly faster than the one before.
PR-URL: https://github.com/nodejs/node/pull/22359
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Diffstat (limited to 'lib/os.js')
-rw-r--r-- | lib/os.js | 67 |
1 files changed, 57 insertions, 10 deletions
@@ -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'); @@ -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 = { |