Skip to content

Commit e2fc667

Browse files
committed
Simplify and optimize quad to hex conversion
1 parent 88afe92 commit e2fc667

File tree

2 files changed

+22
-21
lines changed

2 files changed

+22
-21
lines changed

server/src/main/java/org/elasticsearch/common/network/InetAddresses.java

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -126,26 +126,20 @@ private static byte[] convertDottedQuadToHex(byte[] ipUtf8, int offset, int leng
126126
if (quad == null) {
127127
return null;
128128
}
129-
byte[] penultimate = toHexBytes(((quad[0] & 0xff) << 8) | (quad[1] & 0xff));
130-
byte[] ultimate = toHexBytes(((quad[2] & 0xff) << 8) | (quad[3] & 0xff));
131-
// initialPart + penultimate + ":" + ultimate
132-
byte[] result = new byte[quadOffset + penultimate.length + 1 + ultimate.length];
129+
// initialPart(quadOffset) + penultimate(4) + ":"(1) + ultimate(4)
130+
byte[] result = new byte[quadOffset + 9];
133131
System.arraycopy(ipUtf8, offset, result, 0, quadOffset);
134-
System.arraycopy(penultimate, 0, result, quadOffset, penultimate.length);
135-
result[quadOffset + penultimate.length] = ':';
136-
System.arraycopy(ultimate, 0, result, quadOffset + penultimate.length + 1, ultimate.length);
132+
appendHexBytes(result, quadOffset, quad[0], quad[1]); // penultimate part
133+
result[quadOffset + 4] = ':';
134+
appendHexBytes(result, quadOffset + 5, quad[2], quad[3]); // ultimate part
137135
return result;
138136
}
139137

140-
static byte[] toHexBytes(int val) {
141-
int mag = Integer.SIZE - Integer.numberOfLeadingZeros(val);
142-
int length = Math.max(((mag + 3) / 4), 1);
143-
byte[] result = new byte[length];
144-
for (int i = length - 1; i >= 0; i--) {
145-
result[i] = (byte) HEX_DIGITS[val & 0xf];
146-
val >>>= 4;
147-
}
148-
return result;
138+
static void appendHexBytes(byte[] result, int offset, byte b1, byte b2) {
139+
result[offset] = (byte) HEX_DIGITS[((b1 & 0xf0) >> 4)];
140+
result[offset + 1] = (byte) HEX_DIGITS[(b1 & 0x0f)];
141+
result[offset + 2] = (byte) HEX_DIGITS[((b2 & 0xf0) >> 4)];
142+
result[offset + 3] = (byte) HEX_DIGITS[(b2 & 0x0f)];
149143
}
150144

151145
private static byte[] textToNumericFormatV4(byte[] ipUtf8, int offset, int length, boolean asIpv6) {

server/src/test/java/org/elasticsearch/common/network/InetAddressesTests.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import java.net.InetAddress;
2626
import java.net.NetworkInterface;
2727
import java.net.UnknownHostException;
28+
import java.nio.ByteBuffer;
2829
import java.nio.charset.StandardCharsets;
2930
import java.util.Enumeration;
3031
import java.util.stream.IntStream;
@@ -261,10 +262,16 @@ public void testEncodeAsIpv6() throws Exception {
261262
);
262263
}
263264

264-
public void testToHexBytes() {
265-
IntStream.generate(ESTestCase::randomInt).limit(256).forEach(i -> {
266-
byte[] bytes = InetAddresses.toHexBytes(i);
267-
assertArrayEquals(Integer.toHexString(i).getBytes(StandardCharsets.US_ASCII), bytes);
268-
});
265+
public void testAppendHexBytes() {
266+
for (int i = 0; i < 256; i++) {
267+
byte b1 = randomByte();
268+
byte b2 = randomByte();
269+
// The expected string is the hex representation of the two bytes, padded to 4 characters
270+
String expected = String.format("%1$04x", (b1 & 0xFF) << 8 | b2 & 0xFF);
271+
byte[] hex = new byte[4];
272+
InetAddresses.appendHexBytes(hex, 0, b1, b2);
273+
String actual = new String(hex, StandardCharsets.US_ASCII);
274+
assertEquals(expected, actual);
275+
}
269276
}
270277
}

0 commit comments

Comments
 (0)