@@ -20,9 +20,8 @@ public final class Reader implements Closeable {
2020 'c' , 'o' , 'm' };
2121
2222 private int ipV4Start ;
23- private final Decoder decoder ;
2423 private final Metadata metadata ;
25- private final ThreadBuffer threadBuffer ;
24+ private final BufferHolder bufferHolder ;
2625
2726 /**
2827 * The file mode to use when opening a MaxMind DB.
@@ -63,7 +62,7 @@ public Reader(File database) throws IOException {
6362 * if there is an error reading from the Stream.
6463 */
6564 public Reader (InputStream source ) throws IOException {
66- this (new ThreadBuffer (source ), "<InputStream>" );
65+ this (new BufferHolder (source ), "<InputStream>" );
6766 }
6867
6968 /**
@@ -78,17 +77,17 @@ public Reader(InputStream source) throws IOException {
7877 * if there is an error opening or reading from the file.
7978 */
8079 public Reader (File database , FileMode fileMode ) throws IOException {
81- this (new ThreadBuffer (database , fileMode ), database .getName ());
80+ this (new BufferHolder (database , fileMode ), database .getName ());
8281 }
8382
84- private Reader (ThreadBuffer buffer , String name ) throws IOException {
85- this .threadBuffer = buffer ;
86- int start = this .findMetadataStart (name );
83+ private Reader (BufferHolder bufferHolder , String name ) throws IOException {
84+ this .bufferHolder = bufferHolder ;
8785
88- Decoder metadataDecoder = new Decoder (this .threadBuffer , start );
86+ ByteBuffer buffer = this .bufferHolder .get ();
87+ int start = this .findMetadataStart (buffer , name );
88+
89+ Decoder metadataDecoder = new Decoder (buffer , start );
8990 this .metadata = new Metadata (metadataDecoder .decode (start ).getNode ());
90- this .decoder = new Decoder (this .threadBuffer ,
91- this .metadata .searchTreeSize + DATA_SECTION_SEPARATOR_SIZE );
9291 }
9392
9493 /**
@@ -101,27 +100,28 @@ private Reader(ThreadBuffer buffer, String name) throws IOException {
101100 * if a file I/O error occurs.
102101 */
103102 public JsonNode get (InetAddress ipAddress ) throws IOException {
104- int pointer = this .findAddressInTree (ipAddress );
103+ ByteBuffer buffer = this .bufferHolder .get ();
104+ int pointer = this .findAddressInTree (buffer , ipAddress );
105105 if (pointer == 0 ) {
106106 return null ;
107107 }
108- return this .resolveDataPointer (pointer );
108+ return this .resolveDataPointer (buffer , pointer );
109109 }
110110
111- private int findAddressInTree (InetAddress address )
111+ private int findAddressInTree (ByteBuffer buffer , InetAddress address )
112112 throws InvalidDatabaseException {
113113 byte [] rawAddress = address .getAddress ();
114114
115115 int bitLength = rawAddress .length * 8 ;
116- int record = this .startNode (bitLength );
116+ int record = this .startNode (buffer , bitLength );
117117
118118 for (int i = 0 ; i < bitLength ; i ++) {
119119 if (record >= this .metadata .nodeCount ) {
120120 break ;
121121 }
122122 int b = 0xFF & rawAddress [i / 8 ];
123123 int bit = 1 & (b >> 7 - (i % 8 ));
124- record = this .readNode (record , bit );
124+ record = this .readNode (buffer , record , bit );
125125 }
126126 if (record == this .metadata .nodeCount ) {
127127 // record is empty
@@ -133,18 +133,18 @@ record = this.readNode(record, bit);
133133 throw new InvalidDatabaseException ("Something bad happened" );
134134 }
135135
136- private int startNode (int bitLength ) throws InvalidDatabaseException {
136+ private int startNode (ByteBuffer buffer , int bitLength ) throws InvalidDatabaseException {
137137 // Check if we are looking up an IPv4 address in an IPv6 tree. If this
138138 // is the case, we can skip over the first 96 nodes.
139139 if (this .metadata .ipVersion == 6 && bitLength == 32 ) {
140- return this .ipV4StartNode ();
140+ return this .ipV4StartNode (buffer );
141141 }
142142 // The first node of the tree is always node 0, at the beginning of the
143143 // value
144144 return 0 ;
145145 }
146146
147- private int ipV4StartNode () throws InvalidDatabaseException {
147+ private int ipV4StartNode (ByteBuffer buffer ) throws InvalidDatabaseException {
148148 // This is a defensive check. There is no reason to call this when you
149149 // have an IPv4 tree.
150150 if (this .metadata .ipVersion == 4 ) {
@@ -156,15 +156,14 @@ private int ipV4StartNode() throws InvalidDatabaseException {
156156 }
157157 int node = 0 ;
158158 for (int i = 0 ; i < 96 && node < this .metadata .nodeCount ; i ++) {
159- node = this .readNode (node , 0 );
159+ node = this .readNode (buffer , node , 0 );
160160 }
161161 this .ipV4Start = node ;
162162 return node ;
163163 }
164164
165- private int readNode (int nodeNumber , int index )
165+ private int readNode (ByteBuffer buffer , int nodeNumber , int index )
166166 throws InvalidDatabaseException {
167- ByteBuffer buffer = this .threadBuffer .get ();
168167 int baseOffset = nodeNumber * this .metadata .nodeByteSize ;
169168
170169 switch (this .metadata .recordSize ) {
@@ -190,19 +189,21 @@ private int readNode(int nodeNumber, int index)
190189 }
191190 }
192191
193- private JsonNode resolveDataPointer (int pointer ) throws IOException {
192+ private JsonNode resolveDataPointer (ByteBuffer buffer , int pointer ) throws IOException {
194193 int resolved = (pointer - this .metadata .nodeCount )
195194 + this .metadata .searchTreeSize ;
196195
197- if (resolved >= this . threadBuffer . get () .capacity ()) {
196+ if (resolved >= buffer .capacity ()) {
198197 throw new InvalidDatabaseException (
199198 "The MaxMind DB file's search tree is corrupt: "
200199 + "contains pointer larger than the database." );
201200 }
202201
203202 // We only want the data from the decoder, not the offset where it was
204203 // found.
205- return this .decoder .decode (resolved ).getNode ();
204+ Decoder decoder = new Decoder (buffer ,
205+ this .metadata .searchTreeSize + DATA_SECTION_SEPARATOR_SIZE );
206+ return decoder .decode (resolved ).getNode ();
206207 }
207208
208209 /*
@@ -213,9 +214,8 @@ private JsonNode resolveDataPointer(int pointer) throws IOException {
213214 * are much faster algorithms (e.g., Boyer-Moore) for this if speed is ever
214215 * an issue, but I suspect it won't be.
215216 */
216- private int findMetadataStart (String databaseName )
217+ private int findMetadataStart (ByteBuffer buffer , String databaseName )
217218 throws InvalidDatabaseException {
218- ByteBuffer buffer = this .threadBuffer .get ();
219219 int fileSize = buffer .capacity ();
220220
221221 FILE : for (int i = 0 ; i < fileSize - METADATA_START_MARKER .length + 1 ; i ++) {
@@ -245,6 +245,6 @@ Metadata getMetadata() {
245245 */
246246 @ Override
247247 public void close () throws IOException {
248- this .threadBuffer .close ();
248+ this .bufferHolder .close ();
249249 }
250250}
0 commit comments