Skip to content

Commit dd8ee2e

Browse files
committed
Speed up the decoding of nodes a bit.
1 parent 93fdc58 commit dd8ee2e

2 files changed

Lines changed: 22 additions & 28 deletions

File tree

src/main/java/com/maxmind/maxminddb/Decoder.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,11 @@ long decodeLong(int size) {
268268

269269
long decodeLong(long base, int size) {
270270
ByteBuffer buffer = this.threadBuffer.get();
271+
return Decoder.decodeLong(buffer, base, size);
272+
}
273+
274+
static long decodeLong(ByteBuffer buffer, long base, int size) {
275+
271276
long longInt = base;
272277
for (int i = 0; i < size; i++) {
273278
longInt = (longInt << 8) | (buffer.get() & 0xFF);

src/main/java/com/maxmind/maxminddb/Reader.java

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import java.io.IOException;
55
import java.net.InetAddress;
66
import java.nio.ByteBuffer;
7-
import java.util.Arrays;
87

98
import com.fasterxml.jackson.databind.JsonNode;
109

@@ -107,12 +106,9 @@ long findAddressInTree(InetAddress address) throws MaxMindDbException {
107106
for (int i = 0; i < rawAddress.length * 8; i++) {
108107
int b = 0xFF & rawAddress[i / 8];
109108
int bit = 1 & (b >> 7 - (i % 8));
110-
long[] nodes = this.readNode(nodeNum);
111-
112-
long record = nodes[bit];
109+
long record = this.readNode(nodeNum, bit);
113110

114111
if (this.DEBUG) {
115-
Log.debug("Nodes", Arrays.toString(nodes));
116112
Log.debug("Bit #", i);
117113
Log.debug("Bit value", bit);
118114
Log.debug("Record", bit == 1 ? "right" : "left");
@@ -144,35 +140,28 @@ long record = nodes[bit];
144140
throw new MaxMindDbException("Something bad happened");
145141
}
146142

147-
private long[] readNode(long nodeNumber) throws MaxMindDbException {
143+
private long readNode(long nodeNumber, int index) throws MaxMindDbException {
148144
ByteBuffer buffer = this.threadBuffer.get();
149-
buffer.position((int) nodeNumber * this.metadata.nodeByteSize);
150-
151-
byte[] bytes = Decoder.getByteArray(buffer, this.metadata.nodeByteSize);
152-
153-
if (this.DEBUG) {
154-
Log.debug("Node bytes", bytes);
155-
}
156-
return this.splitNodeIntoRecords(bytes);
157-
}
145+
int baseOffset = (int) nodeNumber * this.metadata.nodeByteSize;
146+
buffer.position(baseOffset);
158147

159-
private long[] splitNodeIntoRecords(byte[] bytes) throws MaxMindDbException {
160-
long[] nodes = new long[2];
161148
switch (this.metadata.recordSize) {
162149
case 24:
163-
nodes[0] = Decoder.decodeLong(Arrays.copyOfRange(bytes, 0, 3));
164-
nodes[1] = Decoder.decodeLong(Arrays.copyOfRange(bytes, 3, 6));
165-
return nodes;
150+
buffer.position(baseOffset + index * 3);
151+
return Decoder.decodeLong(buffer, 0, 3);
166152
case 28:
167-
nodes[0] = Decoder.decodeLong(Arrays.copyOfRange(bytes, 0, 3));
168-
nodes[1] = Decoder.decodeLong(Arrays.copyOfRange(bytes, 4, 7));
169-
nodes[0] = ((0xF0 & bytes[3]) << 20) | nodes[0];
170-
nodes[1] = ((0x0F & bytes[3]) << 24) | nodes[1];
171-
return nodes;
153+
long middle = buffer.get(baseOffset + 3);
154+
155+
if (index == 0) {
156+
middle = (0xF0 & middle) >>> 4;
157+
} else {
158+
middle = 0x0F & middle;
159+
}
160+
buffer.position(baseOffset + index * 4);
161+
return Decoder.decodeLong(buffer, middle, 3);
172162
case 32:
173-
nodes[0] = Decoder.decodeLong(Arrays.copyOfRange(bytes, 0, 4));
174-
nodes[1] = Decoder.decodeLong(Arrays.copyOfRange(bytes, 4, 8));
175-
return nodes;
163+
buffer.position(baseOffset + index * 4);
164+
return Decoder.decodeLong(buffer, 0, 4);
176165
default:
177166
throw new MaxMindDbException("Unknown record size: "
178167
+ this.metadata.recordSize);

0 commit comments

Comments
 (0)