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
34 changes: 20 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ this package directly.

To use the API, you must first create a `Reader` object. The constructor for
the reader object takes a `File` representing your MaxMind DB. Optionally you
may pass a second parameter with a `FileMode` with a value of `MEMORY_MAP` or
`MEMORY`. The default mode is `MEMORY_MAP`, which maps the file to virtual
memory. This often provides performance comparable to loading the file into
real memory with `MEMORY`.
may pass a second parameter with a `FileMode` with a value of `MEMORY_MAPPED`
or `MEMORY`. The default mode is `MEMORY_MAPPED`, which maps the file to
virtual memory. This often provides performance comparable to loading the file
into real memory with `MEMORY`.

To look up an IP address, pass the address as an `InetAddress` to the `get`
method on `Reader`, along with the class of the object you want to
Expand Down Expand Up @@ -251,16 +251,22 @@ threads.

### File Lock on Windows ###

By default, this API uses the `MEMORY_MAP` mode, which memory maps the file.
On Windows, this may create an exclusive lock on the file that prevents it
from being renamed or deleted. Due to the implementation of memory mapping in
Java, this lock will not be released when the `DatabaseReader` is closed; it
will only be released when the object and the `MappedByteBuffer` it uses are
garbage collected. Older JVM versions may also not release the lock on exit.

To work around this problem, use the `MEMORY` mode or try upgrading your JVM
version. You may also call `System.gc()` after dereferencing the
`DatabaseReader` object to encourage the JVM to garbage collect sooner.
By default, this API uses the `MEMORY_MAPPED` mode, which memory maps the file.
On Windows, a live memory mapping may prevent the file from being renamed,
replaced, or deleted. This is not a Java `FileLock`, but it can have similar
effects when updating a database file in place.

Closing the `Reader` releases this library's reference to the mapped buffer,
but Java does not provide a supported way to unmap the underlying
`MappedByteBuffer` immediately. The mapping remains valid until the buffer
becomes unreachable and is garbage collected. Any outstanding lookup or
`Networks` iterator may also keep a duplicate buffer reachable.

To avoid this behavior, use the `MEMORY` mode. If you must use
`MEMORY_MAPPED`, close and dereference the `Reader` and any iterators that were
created from it before replacing the file. You may call `System.gc()` to
encourage earlier cleanup, but garbage collection is not guaranteed to run
immediately.

### Packaging Database in a JAR ###

Expand Down
2 changes: 1 addition & 1 deletion lychee.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# lychee './**/*.md' './src/**/*.java' './pom.xml'

# Include URL fragments in checks
include_fragments = true
include_fragments = "full"

# Don't allow any redirects, so links that have moved are surfaced and updated
# to their canonical destination.
Expand Down
90 changes: 50 additions & 40 deletions mise.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/main/java/com/maxmind/db/CHMCache.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ public CHMCache() {
* Creates a new cache with the specified capacity.
*
* @param capacity
* the maximum number of elements the cache can hold before
* starting to evict them
* the maximum number of elements the cache can hold before it
* stops accepting new entries
*/
public CHMCache(int capacity) {
this.capacity = capacity;
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/maxmind/db/Networks.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ public final class Networks<T> implements Iterator<DatabaseRecord<T>> {
}

/**
* Returns the next DataRecord.
* Returns the next DatabaseRecord.
*
* @return The next DataRecord.
* @return The next DatabaseRecord.
* @throws NetworksIterationException An exception when iterating over the networks.
*/
@Override
Expand Down
29 changes: 18 additions & 11 deletions src/main/java/com/maxmind/db/Reader.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,15 @@ public enum FileMode {
* The default file mode. This maps the database to virtual memory. This
* often provides similar performance to loading the database into real
* memory without the overhead.
*
* <p>On Windows, a live memory mapping may prevent the database file
* from being renamed, replaced, or deleted until the mapped buffer is
* garbage collected.
*/
MEMORY_MAPPED,
/**
* Loads the database into memory when the reader is constructed.
* Loads the database into memory when the reader is constructed. This
* avoids keeping a live memory mapping of the database file.
*/
MEMORY
}
Expand Down Expand Up @@ -240,11 +245,11 @@ long record = traverseResult[0];
* in an IPv6 database. networks() iterates over the canonical locations and
* not the aliases. To include the aliases, you can set includeAliasedNetworks to true.
*
* @param <T> Represents the data type(e.g., Map, HastMap, etc.).
* @param <T> Represents the data type(e.g., Map, HashMap, etc.).
* @param typeParameterClass The type of data returned by the iterator.
* @return Networks The Networks iterator.
* @throws InvalidNetworkException Exception for using an IPv6 network in ipv4-only database.
* @throws ClosedDatabaseException Exception for a closed databased.
* @throws ClosedDatabaseException Exception for a closed database.
* @throws InvalidDatabaseException Exception for an invalid database.
*/
public <T> Networks<T> networks(Class<T> typeParameterClass) throws
Expand All @@ -259,11 +264,11 @@ public <T> Networks<T> networks(Class<T> typeParameterClass) throws
* separately. To set the iteration over the IPv4 networks once, use the
* includeAliasedNetworks option.
*
* @param <T> Represents the data type(e.g., Map, HastMap, etc.).
* @param <T> Represents the data type(e.g., Map, HashMap, etc.).
* @param includeAliasedNetworks Enable including aliased networks.
* @return Networks The Networks iterator.
* @throws InvalidNetworkException Exception for using an IPv6 network in ipv4-only database.
* @throws ClosedDatabaseException Exception for a closed databased.
* @throws ClosedDatabaseException Exception for a closed database.
* @throws InvalidDatabaseException Exception for an invalid database.
*/
public <T> Networks<T> networks(
Expand Down Expand Up @@ -326,13 +331,13 @@ private long findIpV4StartNode(Buffer buffer)
* separately. To only iterate over the IPv4 networks once, use the
* includeAliasedNetworks option.
*
* @param <T> Represents the data type(e.g., Map, HastMap, etc.).
* @param <T> Represents the data type(e.g., Map, HashMap, etc.).
* @param network Specifies the network to be iterated.
* @param includeAliasedNetworks Boolean for including aliased networks.
* @param typeParameterClass The type of data returned by the iterator.
* @return Networks
* @throws InvalidNetworkException Exception for using an IPv6 network in ipv4-only database.
* @throws ClosedDatabaseException Exception for a closed databased.
* @throws ClosedDatabaseException Exception for a closed database.
* @throws InvalidDatabaseException Exception for an invalid database.
*/
public <T> Networks<T> networksWithin(
Expand Down Expand Up @@ -497,10 +502,12 @@ public Metadata getMetadata() {
* </p>
* <p>
* If you are using <code>FileMode.MEMORY_MAPPED</code>, this will
* <em>not</em> unmap the underlying file due to a limitation in Java's
* <code>MappedByteBuffer</code>. It will however set the reference to
* the buffer to <code>null</code>, allowing the garbage collector to
* collect it.
* release this reader's reference to the mapped buffer, allowing the
* garbage collector to collect it when no other references remain. Java
* does not provide a supported way to unmap a
* <code>MappedByteBuffer</code> immediately. On Windows, this means the
* database file may remain unavailable for rename, replacement, or
* deletion until the mapped buffer is garbage collected.
* </p>
*
* @throws IOException if an I/O error occurs.
Expand Down
Loading