Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ CHANGELOG
`MaxMindDbConstructor` and `MaxMindDbParameter` annotations to identify
the constructors and parameters to deserialize into.
* `jackson-databind` is no longer a dependency.
* The `Record` class is now named `DatabaseRecord`. This is to avoid a
conflict with `java.lang.Record` in Java 14.

1.4.0 (2020-06-12)
------------------
Expand Down
9 changes: 1 addition & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,10 @@ import com.maxmind.db.Record;

import java.io.File;
import java.io.IOException;
import java.lang.IllegalAccessException;
import java.lang.InstantiationException;
import java.lang.reflect.InvocationTargetException;
import java.net.InetAddress;

public class Lookup {
public static void main(String[] args)
throws IOException,
InstantiationException,
IllegalAccessException,
InvocationTargetException {
public static void main(String[] args) throws IOException {
File database = new File("/path/to/database/GeoIP2-City.mmdb");
try (Reader reader = new Reader(database)) {
InetAddress address = InetAddress.getByName("24.24.24.24");
Expand Down
24 changes: 3 additions & 21 deletions sample/Benchmark.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import java.io.File;
import java.io.IOException;
import java.lang.IllegalAccessException;
import java.lang.InstantiationException;
import java.lang.reflect.InvocationTargetException;
import java.net.InetAddress;
import java.util.Map;
import java.util.Random;
Expand All @@ -21,12 +18,7 @@ public class Benchmark {
private final static int BENCHMARKS = 5;
private final static boolean TRACE = false;

public static void main(String[] args)
throws IOException,
InstantiationException,
IllegalAccessException,
InvocationTargetException,
NoSuchMethodException {
public static void main(String[] args) throws IOException, InvalidDatabaseException {
File file = new File(args.length > 0 ? args[0] : "GeoLite2-City.mmdb");
System.out.println("No caching");
loop("Warming up", file, WARMUPS, NoCache.getInstance());
Expand All @@ -37,12 +29,7 @@ public static void main(String[] args)
loop("Benchmarking", file, BENCHMARKS, new CHMCache());
}

private static void loop(String msg, File file, int loops, NodeCache cache)
throws IOException,
InstantiationException,
IllegalAccessException,
InvocationTargetException,
NoSuchMethodException {
private static void loop(String msg, File file, int loops, NodeCache cache) throws IOException {
System.out.println(msg);
for (int i = 0; i < loops; i++) {
Reader r = new Reader(file, FileMode.MEMORY_MAPPED, cache);
Expand All @@ -51,12 +38,7 @@ private static void loop(String msg, File file, int loops, NodeCache cache)
System.out.println();
}

private static void bench(Reader r, int count, int seed)
throws IOException,
InstantiationException,
IllegalAccessException,
InvocationTargetException,
NoSuchMethodException {
private static void bench(Reader r, int count, int seed) throws IOException {
Random random = new Random(seed);
long startTime = System.nanoTime();
byte[] address = new byte[4];
Expand Down
10 changes: 1 addition & 9 deletions src/main/java/com/maxmind/db/CHMCache.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@

import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.lang.IllegalAccessException;
import java.lang.InstantiationException;
import java.lang.reflect.InvocationTargetException;

/**
* A simplistic cache using a {@link ConcurrentHashMap}. There's no eviction
Expand All @@ -29,12 +26,7 @@ public CHMCache(int capacity) {
}

@Override
public Object get(CacheKey key, Loader loader)
throws IOException,
InstantiationException,
IllegalAccessException,
InvocationTargetException,
NoSuchMethodException {
public Object get(CacheKey key, Loader loader) throws IOException {
Object value = cache.get(key);
if (value == null) {
value = loader.load(key);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package com.maxmind.db;

import java.io.IOException;

/**
* Signals that no annotated constructor was found. You should annotate a
* constructor in the class with the MaxMindDbConstructor annotation.
*/
public class ConstructorNotFoundException extends IOException {
public class ConstructorNotFoundException extends RuntimeException {
private static final long serialVersionUID = 1L;

ConstructorNotFoundException(String message) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
import java.net.InetAddress;

/**
* Record represents the data and metadata associated with a database lookup.
* DatabaseRecord represents the data and metadata associated with a database
* lookup.
*/
public final class Record<T> {
public final class DatabaseRecord<T> {
private final T data;
private final Network network;

Expand All @@ -16,7 +17,7 @@ public final class Record<T> {
* @param ipAddress the IP address used in the lookup.
* @param prefixLength the network prefix length associated with the record in the database.
*/
public Record(T data, InetAddress ipAddress, int prefixLength) {
public DatabaseRecord(T data, InetAddress ipAddress, int prefixLength) {
this.data = data;
this.network = new Network(ipAddress, prefixLength);
}
Expand Down
101 changes: 46 additions & 55 deletions src/main/java/com/maxmind/db/Decoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.IllegalAccessException;
import java.lang.InstantiationException;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
Expand Down Expand Up @@ -68,12 +66,7 @@ final class Decoder {

private final NodeCache.Loader cacheLoader = this::decode;

public <T> T decode(int offset, Class<T> cls)
throws IOException,
InstantiationException,
IllegalAccessException,
InvocationTargetException,
NoSuchMethodException {
public <T> T decode(int offset, Class<T> cls) throws IOException {
if (offset >= this.buffer.capacity()) {
throw new InvalidDatabaseException(
"The MaxMind DB file's data section contains bad data: "
Expand All @@ -84,12 +77,7 @@ public <T> T decode(int offset, Class<T> cls)
return cls.cast(decode(cls, null));
}

private <T> T decode(CacheKey<T> key)
throws IOException,
InstantiationException,
IllegalAccessException,
InvocationTargetException,
NoSuchMethodException {
private <T> T decode(CacheKey<T> key) throws IOException {
int offset = key.getOffset();
if (offset >= this.buffer.capacity()) {
throw new InvalidDatabaseException(
Expand All @@ -103,11 +91,7 @@ private <T> T decode(CacheKey<T> key)
}

private <T> Object decode(Class<T> cls, java.lang.reflect.Type genericType)
throws IOException,
InstantiationException,
IllegalAccessException,
InvocationTargetException,
NoSuchMethodException {
throws IOException {
int ctrlByte = 0xFF & this.buffer.get();

Type type = Type.fromControlByte(ctrlByte);
Expand Down Expand Up @@ -173,11 +157,7 @@ private <T> Object decodeByType(
int size,
Class<T> cls,
java.lang.reflect.Type genericType
) throws IOException,
InstantiationException,
IllegalAccessException,
InvocationTargetException,
NoSuchMethodException {
) throws IOException {
switch (type) {
case MAP:
return this.decodeMap(size, cls, genericType);
Expand Down Expand Up @@ -302,12 +282,7 @@ private <T, V> List<V> decodeArray(
int size,
Class<T> cls,
Class<V> elementClass
) throws IOException,
InstantiationException,
IllegalAccessException,
InvocationTargetException,
DeserializationException,
NoSuchMethodException {
) throws IOException {
if (!List.class.isAssignableFrom(cls) && !cls.equals(Object.class)) {
throw new DeserializationException();
}
Expand All @@ -316,11 +291,22 @@ private <T, V> List<V> decodeArray(
if (cls.equals(List.class) || cls.equals(Object.class)) {
array = new ArrayList<>(size);
} else {
Constructor<T> constructor = cls.getConstructor(Integer.TYPE);
Constructor<T> constructor;
try {
constructor = cls.getConstructor(Integer.TYPE);
} catch (NoSuchMethodException e) {
throw new DeserializationException("No constructor found for the List: " + e);
}
Object[] parameters = {size};
@SuppressWarnings("unchecked")
List<V> array2 = (List<V>) constructor.newInstance(parameters);
array = array2;
try {
@SuppressWarnings("unchecked")
List<V> array2 = (List<V>) constructor.newInstance(parameters);
array = array2;
} catch (InstantiationException |
IllegalAccessException |
InvocationTargetException e) {
throw new DeserializationException("Error creating list: " + e);
}
}

for (int i = 0; i < size; i++) {
Expand All @@ -335,11 +321,7 @@ private <T> Object decodeMap(
int size,
Class<T> cls,
java.lang.reflect.Type genericType
) throws IOException,
InstantiationException,
IllegalAccessException,
InvocationTargetException,
NoSuchMethodException {
) throws IOException {
if (Map.class.isAssignableFrom(cls) || cls.equals(Object.class)) {
Class<?> valueClass = Object.class;
if (genericType instanceof ParameterizedType) {
Expand All @@ -365,20 +347,27 @@ private <T, V> Map<String, V> decodeMapIntoMap(
Class<T> cls,
int size,
Class<V> valueClass
) throws IOException,
InstantiationException,
IllegalAccessException,
InvocationTargetException,
NoSuchMethodException {
) throws IOException {
Map<String, V> map;
if (cls.equals(Map.class) || cls.equals(Object.class)) {
map = new HashMap<>(size);
} else {
Constructor<T> constructor = cls.getConstructor(Integer.TYPE);
Constructor<T> constructor;
try {
constructor = cls.getConstructor(Integer.TYPE);
} catch (NoSuchMethodException e) {
throw new DeserializationException("No constructor found for the Map: " + e);
}
Object[] parameters = {size};
@SuppressWarnings("unchecked")
Map<String, V> map2 = (Map<String, V>) constructor.newInstance(parameters);
map = map2;
try {
@SuppressWarnings("unchecked")
Map<String, V> map2 = (Map<String, V>) constructor.newInstance(parameters);
map = map2;
} catch (InstantiationException |
IllegalAccessException |
InvocationTargetException e) {
throw new DeserializationException("Error creating map: " + e);
}
}

for (int i = 0; i < size; i++) {
Expand All @@ -391,11 +380,7 @@ private <T, V> Map<String, V> decodeMapIntoMap(
}

private <T> Object decodeMapIntoObject(int size, Class<T> cls)
throws IOException,
InstantiationException,
IllegalAccessException,
InvocationTargetException,
NoSuchMethodException {
throws IOException {
CachedConstructor<T> cachedConstructor = this.constructors.get(cls);
Constructor<T> constructor;
Class<?>[] parameterTypes;
Expand Down Expand Up @@ -448,11 +433,17 @@ private <T> Object decodeMapIntoObject(int size, Class<T> cls)
);
}

return constructor.newInstance(parameters);
try {
return constructor.newInstance(parameters);
} catch (InstantiationException |
IllegalAccessException |
InvocationTargetException e) {
throw new DeserializationException("Error creating object: " + e);
}
}

private static <T> Constructor<T> findConstructor(Class<T> cls)
throws ConstructorNotFoundException {
throws ConstructorNotFoundException {
Constructor<?>[] constructors = cls.getConstructors();
for (Constructor<?> constructor : constructors) {
if (constructor.getAnnotation(MaxMindDbConstructor.class) == null) {
Expand Down
4 changes: 1 addition & 3 deletions src/main/java/com/maxmind/db/DeserializationException.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package com.maxmind.db;

import java.io.IOException;

/**
* Signals that the value could not be deserialized into the type.
*/
public class DeserializationException extends IOException {
public class DeserializationException extends RuntimeException {
private static final long serialVersionUID = 1L;

DeserializationException() {
Expand Down
10 changes: 1 addition & 9 deletions src/main/java/com/maxmind/db/NoCache.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package com.maxmind.db;

import java.io.IOException;
import java.lang.IllegalAccessException;
import java.lang.InstantiationException;
import java.lang.reflect.InvocationTargetException;

/**
* A no-op cache singleton.
Expand All @@ -16,12 +13,7 @@ private NoCache() {
}

@Override
public Object get(CacheKey key, Loader loader)
throws IOException,
InstantiationException,
IllegalAccessException,
InvocationTargetException,
NoSuchMethodException {
public Object get(CacheKey key, Loader loader) throws IOException {
return loader.load(key);
}

Expand Down
17 changes: 2 additions & 15 deletions src/main/java/com/maxmind/db/NodeCache.java
Original file line number Diff line number Diff line change
@@ -1,26 +1,13 @@
package com.maxmind.db;

import java.io.IOException;
import java.lang.IllegalAccessException;
import java.lang.InstantiationException;
import java.lang.reflect.InvocationTargetException;

public interface NodeCache {

interface Loader {
Object load(CacheKey key)
throws IOException,
InstantiationException,
IllegalAccessException,
InvocationTargetException,
NoSuchMethodException;
Object load(CacheKey key) throws IOException;
}

Object get(CacheKey key, Loader loader)
throws IOException,
InstantiationException,
IllegalAccessException,
InvocationTargetException,
NoSuchMethodException;
Object get(CacheKey key, Loader loader) throws IOException;

}
Loading