77
88import com .fasterxml .jackson .databind .JsonNode ;
99
10+ /**
11+ * Instances of this class provide a reader for the MaxMind DB format. IP
12+ * addresses can be looked up using the <code>get</code> method.
13+ */
1014public final class Reader {
1115 private static final int DATA_SECTION_SEPARATOR_SIZE = 16 ;
1216 private static final byte [] METADATA_START_MARKER = { (byte ) 0xAB ,
@@ -18,21 +22,49 @@ public final class Reader {
1822 private final Metadata metadata ;
1923 private final ThreadBuffer threadBuffer ;
2024
25+ /**
26+ * The file mode to use when opening a MaxMind DB.
27+ */
2128 public enum FileMode {
22- MEMORY_MAPPED , IN_MEMORY
29+ /**
30+ * The default file mode. This maps the database to virtual memory. This
31+ * often provides similar performance to loading the database into real
32+ * memory without the overhead.
33+ */
34+ MEMORY_MAPPED ,
35+ /**
36+ * Loads the database into memory when the reader is constructed.
37+ */
38+ IN_MEMORY
2339 }
2440
25- public Reader (File database ) throws MaxMindDbException , IOException {
41+ /**
42+ * Constructs a Reader for the MaxMind DB format. The file passed to it must
43+ * be a valid MaxMind DB file such as a GeoIP2 database file.
44+ *
45+ * @param database
46+ * the MaxMind DB file to use.
47+ * @throws IOException
48+ * if there is an error opening or reading from the file.
49+ */
50+ public Reader (File database ) throws IOException {
2651 this (database , FileMode .MEMORY_MAPPED );
2752 }
2853
29- // XXX - loading the file into memory doesn't really provide any performance
30- // gains on my machine. Consider whether it is even worth providing the
31- // option.
32- public Reader (File database , FileMode mode ) throws MaxMindDbException ,
33- IOException {
54+ /**
55+ * Constructs a Reader for the MaxMind DB format. The file passed to it must
56+ * be a valid MaxMind DB file such as a GeoIP2 database file.
57+ *
58+ * @param database
59+ * the MaxMind DB file to use.
60+ * @param fileMode
61+ * the mode to open the file with.
62+ * @throws IOException
63+ * if there is an error opening or reading from the file.
64+ */
65+ public Reader (File database , FileMode fileMode ) throws IOException {
3466 this .DEBUG = System .getenv ().get ("MAXMIND_DB_READER_DEBUG" ) != null ;
35- this .threadBuffer = new ThreadBuffer (database , mode );
67+ this .threadBuffer = new ThreadBuffer (database , fileMode );
3668
3769 /*
3870 * We need to make sure that whatever chunk we read will have the
@@ -51,7 +83,7 @@ public Reader(File database, FileMode mode) throws MaxMindDbException,
5183 long start = this .findMetadataStart ();
5284
5385 if (start < 0 ) {
54- throw new MaxMindDbException (
86+ throw new InvalidDatabaseException (
5587 "Could not find a MaxMind DB metadata marker in this file ("
5688 + database .getName ()
5789 + "). Is this a valid MaxMind DB file?" );
@@ -69,10 +101,18 @@ public Reader(File database, FileMode mode) throws MaxMindDbException,
69101 }
70102 }
71103
72- public JsonNode get (InetAddress address ) throws MaxMindDbException ,
73- IOException {
104+ /**
105+ * Looks up the <code>address</code> in the MaxMind DB.
106+ *
107+ * @param ipAddress
108+ * the IP address to look up.
109+ * @return the record for the IP address.
110+ * @throws IOException
111+ * if a file I/O error occurs.
112+ */
113+ public JsonNode get (InetAddress ipAddress ) throws IOException {
74114
75- long pointer = this .findAddressInTree (address );
115+ long pointer = this .findAddressInTree (ipAddress );
76116
77117 if (pointer == 0 ) {
78118 return null ;
@@ -83,7 +123,7 @@ public JsonNode get(InetAddress address) throws MaxMindDbException,
83123 }
84124
85125 private long findAddressInTree (InetAddress address )
86- throws MaxMindDbException {
126+ throws InvalidDatabaseException {
87127 byte [] rawAddress = address .getAddress ();
88128
89129 if (this .DEBUG ) {
@@ -138,10 +178,11 @@ long record = this.readNode(nodeNum, bit);
138178 nodeNum = record ;
139179 }
140180
141- throw new MaxMindDbException ("Something bad happened" );
181+ throw new InvalidDatabaseException ("Something bad happened" );
142182 }
143183
144- private long readNode (long nodeNumber , int index ) throws MaxMindDbException {
184+ private long readNode (long nodeNumber , int index )
185+ throws InvalidDatabaseException {
145186 ByteBuffer buffer = this .threadBuffer .get ();
146187 int baseOffset = (int ) nodeNumber * this .metadata .nodeByteSize ;
147188 buffer .position (baseOffset );
@@ -164,13 +205,12 @@ private long readNode(long nodeNumber, int index) throws MaxMindDbException {
164205 buffer .position (baseOffset + index * 4 );
165206 return Decoder .decodeLong (buffer , 0 , 4 );
166207 default :
167- throw new MaxMindDbException ("Unknown record size: "
208+ throw new InvalidDatabaseException ("Unknown record size: "
168209 + this .metadata .recordSize );
169210 }
170211 }
171212
172- private JsonNode resolveDataPointer (long pointer )
173- throws MaxMindDbException , IOException {
213+ private JsonNode resolveDataPointer (long pointer ) throws IOException {
174214 long resolved = (pointer - this .metadata .nodeCount )
175215 + this .metadata .searchTreeSize ;
176216
@@ -216,6 +256,12 @@ Metadata getMetadata() {
216256 return this .metadata ;
217257 }
218258
259+ /**
260+ * Closes the MaxMind DB and returns resources to the system.
261+ *
262+ * @throws IOException
263+ * if an I/O error occurs.
264+ */
219265 public void close () throws IOException {
220266 this .threadBuffer .close ();
221267 }
0 commit comments