diff --git a/binding/java/ReadMe.md b/binding/java/ReadMe.md index 363fbe0..7471578 100644 --- a/binding/java/ReadMe.md +++ b/binding/java/ReadMe.md @@ -7,7 +7,7 @@ org.lionsoul ip2region - 3.3.0 + 3.3.1 ``` @@ -21,6 +21,8 @@ import org.lionsoul.ip2region.service.Ip2Region; final Config v4Config = Config.custom() .setCachePolicy(Config.VIndexCache) // 指定缓存策略: NoCache / VIndexCache / BufferCache .setSearchers(15) // 设置初始化的查询器数量 + // .setXdbInputStream(InputStream) // 设置 v4 xdb 文件的 inputstream 对象 + // .setXdbFile(File) // 设置 v4 xdb File 对象 .setXdbPath("ip2region v4 xdb path") // 设置 v4 xdb 文件的路径 .asV4(); // 指定为 v4 配置 @@ -28,9 +30,13 @@ final Config v4Config = Config.custom() final Config v6Config = Config.custom() .setCachePolicy(Config.VIndexCache) // 指定缓存策略: NoCache / VIndexCache / BufferCache .setSearchers(15) // 设置初始化的查询器数量 + // .setXdbInputStream(InputStream) // 设置 v6 xdb 文件的 inputstream 对象 + // .setXdbFile(File) // 设置 v6 xdb File 对象 .setXdbPath("ip2region v6 xdb path") // 设置 v6 xdb 文件的路径 .asV6(); // 指定为 v6 配置 +// 备注:Xdb 三种初始化输入的优先级:XdbInputStream -> XdbFile -> XdbPath + // 3,通过上述配置创建 Ip2Region 查询服务 final Ip2Region ip2Region = Ip2Region.create(v4Config, v6Config); diff --git a/binding/java/pom.xml b/binding/java/pom.xml index ce1b62d..248795b 100644 --- a/binding/java/pom.xml +++ b/binding/java/pom.xml @@ -4,7 +4,7 @@ org.lionsoul ip2region - 3.3.0 + 3.3.1 jar ip2region diff --git a/binding/java/src/main/java/org/lionsoul/ip2region/SearcherTest.java b/binding/java/src/main/java/org/lionsoul/ip2region/SearcherTest.java index 279160f..33506f9 100644 --- a/binding/java/src/main/java/org/lionsoul/ip2region/SearcherTest.java +++ b/binding/java/src/main/java/org/lionsoul/ip2region/SearcherTest.java @@ -7,7 +7,7 @@ package org.lionsoul.ip2region; import org.lionsoul.ip2region.service.Config; -import org.lionsoul.ip2region.service.InvalidCachePolicyException; +import org.lionsoul.ip2region.service.InvalidConfigException; import org.lionsoul.ip2region.service.Ip2Region; import org.lionsoul.ip2region.xdb.InetAddressException; import org.lionsoul.ip2region.xdb.XdbException; @@ -49,7 +49,7 @@ public class SearcherTest { } public static final Ip2Region createService( - String v4XdbPath, String v4CachePolicy, String v6XdbPath, String v6CachePolicy) throws IOException, XdbException, InvalidCachePolicyException { + String v4XdbPath, String v4CachePolicy, String v6XdbPath, String v6CachePolicy) throws IOException, XdbException, InvalidConfigException { final Config v4Config = Config.custom() .setCachePolicy(Config.cachePolicyFromName(v4CachePolicy)) .setSearchers(1) @@ -89,7 +89,7 @@ public class SearcherTest { } } - public static void searchTest(String[] args) throws IOException, XdbException, InvalidCachePolicyException, InterruptedException { + public static void searchTest(String[] args) throws IOException, XdbException, InterruptedException, InvalidConfigException { String help = ""; String v4DbPath = "", v4CachePolicy = "vectorIndex"; String v6DbPath = "", v6CachePolicy = "vectorIndex"; diff --git a/binding/java/src/main/java/org/lionsoul/ip2region/service/Config.java b/binding/java/src/main/java/org/lionsoul/ip2region/service/Config.java index 8e8388b..0cb938c 100644 --- a/binding/java/src/main/java/org/lionsoul/ip2region/service/Config.java +++ b/binding/java/src/main/java/org/lionsoul/ip2region/service/Config.java @@ -4,6 +4,7 @@ package org.lionsoul.ip2region.service; +import java.io.File; import java.io.IOException; import org.lionsoul.ip2region.xdb.Header; @@ -22,12 +23,15 @@ public class Config { public static final int VIndexCache = 1; public static final int BufferCache = 2; + // alias of BufferCache but easier to understand or Remember + public static final int FullCache = 2; + // search cache policy public final int cachePolicy; public final Version ipVersion; // xdb file path - public final String xdbPath; + public final File xdbFile; public final Header header; public final byte[] vIndex; @@ -40,21 +44,21 @@ public class Config { return new ConfigBuilder(); } - protected Config(int cachePolicy, Version ipVersion, String xdbPath, + protected Config(int cachePolicy, Version ipVersion, File xdbFile, Header header, byte[] vIndex, LongByteArray cBuffer, int searchers) throws IOException, XdbException { this.cachePolicy = cachePolicy; this.ipVersion = ipVersion; - this.xdbPath = xdbPath; - this.header = header; - this.vIndex = vIndex; + this.xdbFile = xdbFile; + this.header = header; + this.vIndex = vIndex; this.cBuffer = cBuffer; final Version xVersion = Version.fromHeader(header); // verify the ip version (ipVersion and the version of the xdb file should be the same) if (header.ipVersion != ipVersion.id) { throw new XdbException("ip verison not match: xdb file " - + xdbPath + " (" + xVersion.name + "), as " + ipVersion.name + " expected"); + + xdbFile.getAbsolutePath() + " (" + xVersion.name + "), as " + ipVersion.name + " expected"); } this.searchers = searchers; @@ -65,7 +69,7 @@ public class Config { sb.append('{'); sb.append("cache_policy:").append(cachePolicy).append(','); sb.append("version:").append(ipVersion.toString()).append(','); - sb.append("xdb_path:").append(xdbPath).append(','); + sb.append("xdb_path:").append(xdbFile == null ? "null" : xdbFile.getAbsolutePath()).append(','); sb.append("header:").append(header.toString()).append(','); if (vIndex == null) { sb.append("v_index: null, "); @@ -82,7 +86,7 @@ public class Config { return sb.toString(); } - public static final int cachePolicyFromName(String name) throws InvalidCachePolicyException { + public static final int cachePolicyFromName(String name) throws InvalidConfigException { final String lName = name.toLowerCase(); if (lName.equals("file") || lName.equals("nocache")) { return NoCache; @@ -91,7 +95,7 @@ public class Config { } else if (lName.equals("content") || lName.equals("buffercache")) { return BufferCache; } else { - throw new InvalidCachePolicyException("invalid cache policy `" + name + "`"); + throw new InvalidConfigException("invalid cache policy `" + name + "`"); } } } \ No newline at end of file diff --git a/binding/java/src/main/java/org/lionsoul/ip2region/service/ConfigBuilder.java b/binding/java/src/main/java/org/lionsoul/ip2region/service/ConfigBuilder.java index dd838bd..06dd6d6 100644 --- a/binding/java/src/main/java/org/lionsoul/ip2region/service/ConfigBuilder.java +++ b/binding/java/src/main/java/org/lionsoul/ip2region/service/ConfigBuilder.java @@ -4,7 +4,9 @@ package org.lionsoul.ip2region.service; +import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.io.RandomAccessFile; import org.lionsoul.ip2region.xdb.Header; @@ -23,8 +25,11 @@ public class ConfigBuilder { // cache policy private int cachePolicy = Config.VIndexCache; - // xdb file path + // xdb file path / Object / InputStream. + // Priority: InputStream -> File Object -> String path private String xdbPath = null; + private File xdbFile = null; + private InputStream xdbInputStream = null; // searchers private int searchers = 20; @@ -45,14 +50,53 @@ public class ConfigBuilder { return this; } + public ConfigBuilder setXdbFile(File xdbFile) { + this.xdbFile = xdbFile; + return this; + } + + public ConfigBuilder setXdbInputStream(InputStream xdbInputStream) { + this.xdbInputStream = xdbInputStream; + return this; + } + public ConfigBuilder setSearchers(int searchers) { this.searchers = searchers; return this; } - private Config build(Version ipVersion) throws IOException, XdbException { + private Config build(Version ipVersion) throws IOException, XdbException, InvalidConfigException { + if (xdbInputStream == null) { + // everyting is fine + } else if (cachePolicy != Config.BufferCache) { + // @Note: we can't directly rewrite the cachePolicy to Config.BufferCache. + // you must know what you are doing. + throw new InvalidConfigException("SetXdbInputStream could ONLY be used with cachePolicy = Config.BufferCache"); + } else { + // 1, load the content buffer + final LongByteArray cBuffer = Searcher.loadContentFromInputStream(xdbInputStream); + + // 2, verify the xdb from the buffer + Searcher.verify(Searcher.loadHeaderFromBuffer(cBuffer), cBuffer.length()); + + // 3, load the header + final Header header = Searcher.loadHeaderFromBuffer(cBuffer); + + // create the config without xdbFile and vIndex + return new Config(cachePolicy, ipVersion, null, header, null, cBuffer, searchers); + } + // load the header and the cache buffer - final RandomAccessFile raf = new RandomAccessFile(xdbPath, "r"); + final File xdbFile; + if (this.xdbFile != null) { + xdbFile = this.xdbFile; + } else if (this.xdbPath != null) { + xdbFile = new File(this.xdbPath); + } else { + throw new InvalidConfigException("Both xdbFile and xdbPath is null"); + } + + final RandomAccessFile raf = new RandomAccessFile(xdbFile, "r"); // 1, verify the xdb Searcher.verify(raf); @@ -67,16 +111,16 @@ public class ConfigBuilder { final LongByteArray cBuffer = cachePolicy == Config.BufferCache ? Searcher.loadContent(raf) : null; raf.close(); - return new Config(cachePolicy, ipVersion, xdbPath, header, vIndex, cBuffer, searchers); + return new Config(cachePolicy, ipVersion, xdbFile, header, vIndex, cBuffer, searchers); } // build the final #Config instance for IPv4 - public Config asV4() throws IOException, XdbException { + public Config asV4() throws IOException, XdbException, InvalidConfigException { return build(Version.IPv4); } // build the final #Config instance for IPv6 - public Config asV6() throws IOException, XdbException { + public Config asV6() throws IOException, XdbException, InvalidConfigException { return build(Version.IPv6); } diff --git a/binding/java/src/main/java/org/lionsoul/ip2region/service/InvalidCachePolicyException.java b/binding/java/src/main/java/org/lionsoul/ip2region/service/InvalidCachePolicyException.java deleted file mode 100644 index 348e58f..0000000 --- a/binding/java/src/main/java/org/lionsoul/ip2region/service/InvalidCachePolicyException.java +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2022 The Ip2Region Authors. All rights reserved. -// Use of this source code is governed by a Apache2.0-style -// license that can be found in the LICENSE file. - -package org.lionsoul.ip2region.service; - -public class InvalidCachePolicyException extends Exception { - public InvalidCachePolicyException(String str) { - super(str); - } -} diff --git a/binding/java/src/main/java/org/lionsoul/ip2region/service/InvalidConfigException.java b/binding/java/src/main/java/org/lionsoul/ip2region/service/InvalidConfigException.java new file mode 100644 index 0000000..a46a00c --- /dev/null +++ b/binding/java/src/main/java/org/lionsoul/ip2region/service/InvalidConfigException.java @@ -0,0 +1,7 @@ +package org.lionsoul.ip2region.service; + +public class InvalidConfigException extends Exception { + public InvalidConfigException(String str) { + super(str); + } +} diff --git a/binding/java/src/main/java/org/lionsoul/ip2region/service/Ip2Region.java b/binding/java/src/main/java/org/lionsoul/ip2region/service/Ip2Region.java index a6fc03a..d55073b 100644 --- a/binding/java/src/main/java/org/lionsoul/ip2region/service/Ip2Region.java +++ b/binding/java/src/main/java/org/lionsoul/ip2region/service/Ip2Region.java @@ -4,6 +4,7 @@ package org.lionsoul.ip2region.service; +import java.io.File; import java.io.IOException; import org.lionsoul.ip2region.xdb.InetAddressException; @@ -37,23 +38,28 @@ public class Ip2Region { return new Ip2Region(v4Config, v6Config).init(); } - public static final Ip2Region create(final String v4XdbPath, final String v6XdbPath) throws IOException, XdbException { - return new Ip2Region(v4XdbPath, v6XdbPath).init(); + public static final Ip2Region create(final String v4XdbPath, final String v6XdbPath) throws IOException, XdbException, InvalidConfigException { + return new Ip2Region(new File(v4XdbPath), new File(v6XdbPath)).init(); + } + + public static final Ip2Region create(final File v4XdbFile, final File v6XdbFile) throws IOException, XdbException, InvalidConfigException { + return new Ip2Region(v4XdbFile, v6XdbFile).init(); } /** * init the ip2reigon with two xdb file path and default cachePolicy vIndex. * set it to null to disabled the search for specified version * - * @param v4XdbPath - * @param v6XdbPath + * @param v4XdbFile + * @param v6XdbFile * @throws XdbException * @throws IOException + * @throws InvalidConfigException */ - protected Ip2Region(String v4XdbPath, String v6XdbPath) throws IOException, XdbException { + protected Ip2Region(File v4XdbFile, File v6XdbFile) throws IOException, XdbException, InvalidConfigException { this( - v4XdbPath == null ? null : Config.custom().setXdbPath(v4XdbPath).asV4(), - v6XdbPath == null ? null : Config.custom().setXdbPath(v6XdbPath).asV6() + v4XdbFile == null ? null : Config.custom().setXdbFile(v4XdbFile).asV4(), + v6XdbFile == null ? null : Config.custom().setXdbFile(v6XdbFile).asV6() ); } diff --git a/binding/java/src/main/java/org/lionsoul/ip2region/service/SearcherPool.java b/binding/java/src/main/java/org/lionsoul/ip2region/service/SearcherPool.java index 48c7473..aa97e00 100644 --- a/binding/java/src/main/java/org/lionsoul/ip2region/service/SearcherPool.java +++ b/binding/java/src/main/java/org/lionsoul/ip2region/service/SearcherPool.java @@ -60,7 +60,7 @@ public class SearcherPool { protected SearcherPool init() throws IOException { // create the searchers for (int i = pool.size(); i < config.searchers; i++) { - final Searcher searcher = new Searcher(config.ipVersion, config.xdbPath, config.vIndex, config.cBuffer); + final Searcher searcher = new Searcher(config.ipVersion, config.xdbFile, config.vIndex, config.cBuffer); pool.add(searcher); } diff --git a/binding/java/src/main/java/org/lionsoul/ip2region/xdb/Header.java b/binding/java/src/main/java/org/lionsoul/ip2region/xdb/Header.java index 4b73150..2a1bbc4 100644 --- a/binding/java/src/main/java/org/lionsoul/ip2region/xdb/Header.java +++ b/binding/java/src/main/java/org/lionsoul/ip2region/xdb/Header.java @@ -33,13 +33,13 @@ public class Header { @Override public String toString() { return "{" + - "Version: " + version + ',' + - "IndexPolicy: " + indexPolicy + ',' + - "CreatedAt: " + createdAt + ',' + - "StartIndexPtr: " + startIndexPtr + ',' + - "EndIndexPtr: " + endIndexPtr + ',' + - "IPVersion: " + ipVersion + ',' + - "RuntimePtrBytes: " + runtimePtrBytes + + "Version:" + version + ',' + + "IndexPolicy:" + indexPolicy + ',' + + "CreatedAt:" + createdAt + ',' + + "StartIndexPtr:" + startIndexPtr + ',' + + "EndIndexPtr:" + endIndexPtr + ',' + + "IPVersion:" + ipVersion + ',' + + "RuntimePtrBytes:" + runtimePtrBytes + '}'; } } diff --git a/binding/java/src/main/java/org/lionsoul/ip2region/xdb/Searcher.java b/binding/java/src/main/java/org/lionsoul/ip2region/xdb/Searcher.java index 5dd22c4..6152cdd 100644 --- a/binding/java/src/main/java/org/lionsoul/ip2region/xdb/Searcher.java +++ b/binding/java/src/main/java/org/lionsoul/ip2region/xdb/Searcher.java @@ -4,11 +4,14 @@ package org.lionsoul.ip2region.xdb; +import java.io.File; + // xdb searcher (Not thread safe implementation) // @Author Lion // @Date 2022/06/23 import java.io.IOException; +import java.io.InputStream; import java.io.RandomAccessFile; public class Searcher { @@ -29,7 +32,7 @@ public class Searcher { private final Version version; // random access file handle for file-based search - private final String xdbPath; + private final File xdbFile; private final RandomAccessFile handle; private int ioCount = 0; @@ -46,12 +49,20 @@ public class Searcher { // --- static method to create searchers - public static Searcher newWithFileOnly(Version version, String dbPath) throws IOException { - return new Searcher(version, dbPath, null, null); + public static Searcher newWithFileOnly(Version version, String xdbPath) throws IOException { + return new Searcher(version, new File(xdbPath), null, null); } - public static Searcher newWithVectorIndex(Version version, String dbPath, byte[] vectorIndex) throws IOException { - return new Searcher(version, dbPath, vectorIndex, null); + public static Searcher newWithFileOnly(Version version, File xdbFile) throws IOException { + return new Searcher(version, xdbFile, null, null); + } + + public static Searcher newWithVectorIndex(Version version, String xdbPath, byte[] vectorIndex) throws IOException { + return new Searcher(version, new File(xdbPath), vectorIndex, null); + } + + public static Searcher newWithVectorIndex(Version version, File xdbFile, byte[] vectorIndex) throws IOException { + return new Searcher(version, xdbFile, vectorIndex, null); } public static Searcher newWithBuffer(Version version, LongByteArray cBuff) throws IOException { @@ -60,15 +71,15 @@ public class Searcher { // --- End of creator - public Searcher(Version version, String dbFile, byte[] vectorIndex, LongByteArray cBuff) throws IOException { + public Searcher(Version version, File xdbFile, byte[] vectorIndex, LongByteArray cBuff) throws IOException { this.version = version; - this.xdbPath = dbFile; + this.xdbFile = xdbFile; if (cBuff != null) { this.handle = null; this.vectorIndex = null; this.contentBuff = cBuff; } else { - this.handle = new RandomAccessFile(dbFile, "r"); + this.handle = new RandomAccessFile(xdbFile, "r"); this.vectorIndex = vectorIndex; this.contentBuff = null; } @@ -179,13 +190,15 @@ public class Searcher { return String.format( "%s->{version:%s, xdb:%s, vIndex:%s, cBuffer:%s}", super.toString(), - version.name, xdbPath, + version.name, xdbFile == null ? "null" : xdbFile.getAbsolutePath(), vectorIndex == null ? "null" : String.valueOf(vectorIndex.length), contentBuff == null ? "null" : String.valueOf(contentBuff.length()) ); } + // --- // --- static util function + // --- read xdb header public static Header loadHeader(RandomAccessFile handle) throws IOException { handle.seek(0); @@ -194,13 +207,23 @@ public class Searcher { return new Header(buff); } - public static Header loadHeaderFromFile(String dbPath) throws IOException { - final RandomAccessFile handle = new RandomAccessFile(dbPath, "r"); + public static Header loadHeaderFromFile(File xdbFile) throws IOException { + final RandomAccessFile handle = new RandomAccessFile(xdbFile, "r"); final Header header = loadHeader(handle); handle.close(); return header; } + public static Header loadHeaderFromFile(String xdbPath) throws IOException { + return loadHeaderFromFile(new File(xdbPath)); + } + + public static Header loadHeaderFromBuffer(LongByteArray cBuffer) throws IOException { + return new Header(cBuffer.slice(0, HeaderInfoLength)); + } + + // --- read xdb vector index + public static byte[] loadVectorIndex(RandomAccessFile handle) throws IOException { handle.seek(HeaderInfoLength); int len = VectorIndexRows * VectorIndexCols * VectorIndexSize; @@ -213,13 +236,24 @@ public class Searcher { return buff; } - public static byte[] loadVectorIndexFromFile(String dbPath) throws IOException { - final RandomAccessFile handle = new RandomAccessFile(dbPath, "r"); + public static byte[] loadVectorIndexFromFile(File xdbFile) throws IOException { + final RandomAccessFile handle = new RandomAccessFile(xdbFile, "r"); final byte[] vIndex = loadVectorIndex(handle); handle.close(); return vIndex; } + public static byte[] loadVectorIndexFromFile(String xdbPath) throws IOException { + return loadVectorIndexFromFile(new File(xdbPath)); + } + + public static byte[] loadVectorIndexFromBuffer(LongByteArray cBuffer) throws IOException { + final int len = VectorIndexRows * VectorIndexCols * VectorIndexSize; + return cBuffer.slice(HeaderInfoLength, len); + } + + // --- read xdb content + public static LongByteArray loadContent(RandomAccessFile handle) throws IOException { handle.seek(0); // check the length and do the buff load @@ -239,13 +273,56 @@ public class Searcher { return byteArray; } - public static LongByteArray loadContentFromFile(String dbPath) throws IOException { - final RandomAccessFile handle = new RandomAccessFile(dbPath, "r"); + public static LongByteArray loadContentFromFile(File xdbFile) throws IOException { + final RandomAccessFile handle = new RandomAccessFile(xdbFile, "r"); final LongByteArray content = loadContent(handle); handle.close(); return content; } + public static LongByteArray loadContentFromFile(String xdbPath) throws IOException { + return loadContentFromFile(new File(xdbPath)); + } + + public static LongByteArray loadContentFromInputStream(InputStream is) throws IOException { + final LongByteArray byteArray = new LongByteArray(); + while (true) { + boolean done = false; + + // read at most MAX_WRITE_BYTES bytes + int rLen, tBytes = 0; + final byte[] buff = new byte[MAX_WRITE_BYTES]; + while (true) { + rLen = is.read(buff, tBytes, buff.length - tBytes); + if (rLen == -1) { + // reach the end of the stream + done = true; + break; + } else if (rLen == 0) { + // the entire buff was filled + break; + } + + tBytes += rLen; + } + + // check and copy the buffer with its actual filled bytes + if (tBytes == buff.length) { + byteArray.append(buff); + } else { + final byte[] nBuff = new byte[tBytes]; + System.arraycopy(buff, 0, nBuff, 0, tBytes); + byteArray.append(nBuff); + } + + if (done) { + break; + } + } + + return byteArray; + } + // --- verify util function // Verify if the current Searcher could be used to search the specified xdb file. @@ -254,9 +331,7 @@ public class Searcher { // // @Note: You Just need to check this ONCE when the service starts // Or use another process (eg, A command) to check once Just to confirm the suitability. - public static void verify(RandomAccessFile handle) throws IOException, XdbException { - final Header header = loadHeader(handle); - + public static void verify(Header header, long fileBytes) throws IOException, XdbException { // get the runtime ptr bytes int runtimePtrBytes = 0; if (header.version == STRUCTURE_20) { @@ -270,15 +345,23 @@ public class Searcher { // 1, confirm the xdb file size // to ensure that the maximum file pointer does not overflow final long maxFilePtr = (1L << (runtimePtrBytes * 8)) - 1; - if (handle.length() > maxFilePtr) { + if (fileBytes > maxFilePtr) { throw new XdbException("xdb file exceeds the maximum supported bytes: "+maxFilePtr+""); } } - public static void verifyFromFile(String dbFile) throws IOException, XdbException { - final RandomAccessFile handle = new RandomAccessFile(dbFile, "r"); + public static void verify(RandomAccessFile handle) throws IOException, XdbException { + verify(loadHeader(handle), handle.length()); + } + + public static void verifyFromFile(File xdbFile) throws IOException, XdbException { + final RandomAccessFile handle = new RandomAccessFile(xdbFile, "r"); verify(handle); handle.close(); } + public static void verifyFromFile(String xdbPath) throws IOException, XdbException { + verifyFromFile(new File(xdbPath)); + } + } \ No newline at end of file diff --git a/binding/java/src/test/java/org/lionsoul/ip2region/service/ConfigTest.java b/binding/java/src/test/java/org/lionsoul/ip2region/service/ConfigTest.java index 56a5b66..ef26581 100644 --- a/binding/java/src/test/java/org/lionsoul/ip2region/service/ConfigTest.java +++ b/binding/java/src/test/java/org/lionsoul/ip2region/service/ConfigTest.java @@ -1,4 +1,6 @@ package org.lionsoul.ip2region.service; +import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.security.CodeSource; @@ -21,9 +23,9 @@ public class ConfigTest { } @Test - public void testBuildV4Config() throws IOException, XdbException { + public void testBuildV4Config() throws IOException, XdbException, InvalidConfigException { final Config v4Config = Config.custom() - .setCachePolicy(Config.BufferCache) + .setCachePolicy(Config.VIndexCache) .setXdbPath(getDataPath("ip2region_v4.xdb")) .setSearchers(20) .asV4(); @@ -31,7 +33,29 @@ public class ConfigTest { } @Test - public void testBuildV6Config() throws IOException, XdbException { + public void testBuildV4ConfigFromFile() throws IOException, XdbException, InvalidConfigException { + final Config v4Config = Config.custom() + .setCachePolicy(Config.BufferCache) + .setXdbFile(new File(getDataPath("ip2region_v4.xdb"))) + .setSearchers(20) + .asV4(); + log.debugf("builded config: %s", v4Config); + } + + @Test + public void testBuildV4ConfigFromInputStream() throws IOException, XdbException, InvalidConfigException { + final Config v4Config = Config.custom() + .setCachePolicy(Config.BufferCache) + .setXdbInputStream(new FileInputStream(getDataPath("ip2region_v4.xdb"))) + .setSearchers(20) + .asV4(); + log.debugf("builded config: %s", v4Config); + } + + // --- IPv6 + + @Test + public void testBuildV6Config() throws IOException, XdbException, InvalidConfigException { final Config v4Config = Config.custom() .setCachePolicy(Config.VIndexCache) .setXdbPath(getDataPath("ip2region_v6.xdb")) @@ -39,4 +63,25 @@ public class ConfigTest { .asV6(); log.debugf("builded config: %s", v4Config); } + + @Test + public void testBuildV6ConfigFromFile() throws IOException, XdbException, InvalidConfigException { + final Config v4Config = Config.custom() + .setCachePolicy(Config.BufferCache) + .setXdbFile(new File(getDataPath("ip2region_v6.xdb"))) + .setSearchers(20) + .asV6(); + log.debugf("builded config: %s", v4Config); + } + + @Test + public void testBuildV6ConfigFromInputStream() throws IOException, XdbException, InvalidConfigException { + final Config v4Config = Config.custom() + .setCachePolicy(Config.BufferCache) + .setXdbInputStream(new FileInputStream(getDataPath("ip2region_v6.xdb"))) + .setSearchers(20) + .asV6(); + log.debugf("builded config: %s", v4Config); + } + } diff --git a/binding/java/src/test/java/org/lionsoul/ip2region/service/Ip2RegionTest.java b/binding/java/src/test/java/org/lionsoul/ip2region/service/Ip2RegionTest.java index d0fcab7..d78829d 100644 --- a/binding/java/src/test/java/org/lionsoul/ip2region/service/Ip2RegionTest.java +++ b/binding/java/src/test/java/org/lionsoul/ip2region/service/Ip2RegionTest.java @@ -17,7 +17,7 @@ public class Ip2RegionTest { private static final Log log = Log.getLogger(Ip2RegionTest.class).setLevel(Log.DEBUG); @Test - public void TestConfigCreate() throws IOException, XdbException, InetAddressException, InterruptedException { + public void TestConfigCreate() throws IOException, XdbException, InetAddressException, InterruptedException, InvalidConfigException { final Config v4Config = Config.custom() .setCachePolicy(Config.NoCache) .setSearchers(10) @@ -46,7 +46,7 @@ public class Ip2RegionTest { } @Test - public void TestPathCreate() throws InetAddressException, IOException, XdbException, InterruptedException { + public void TestPathCreate() throws InetAddressException, IOException, XdbException, InterruptedException, InvalidConfigException { byte[] v4Bytes = Util.parseIP("113.92.157.29"); byte[] v6Bytes = Util.parseIP("240e:3b7:3272:d8d0:db09:c067:8d59:539e"); final Ip2Region ip2Region = Ip2Region.create(ConfigTest.getDataPath("ip2region_v4.xdb"), ConfigTest.getDataPath("ip2region_v6.xdb")); @@ -63,7 +63,7 @@ public class Ip2RegionTest { } @Test - public void TestInMemSearch() throws IOException, XdbException, InetAddressException, InterruptedException { + public void TestInMemSearch() throws IOException, XdbException, InetAddressException, InterruptedException, InvalidConfigException { final Config v4Config = Config.custom() .setCachePolicy(Config.BufferCache) .setXdbPath(ConfigTest.getDataPath("ip2region_v4.xdb")) @@ -90,7 +90,7 @@ public class Ip2RegionTest { } @Test - public void TestConcurrentCall() throws IOException, XdbException, InetAddressException, InterruptedException { + public void TestConcurrentCall() throws IOException, XdbException, InetAddressException, InterruptedException, InvalidConfigException { final Config v4Config = Config.custom() .setCachePolicy(Config.VIndexCache) .setSearchers(15) @@ -144,7 +144,7 @@ public class Ip2RegionTest { } @Test - public void TestV4Only() throws IOException, XdbException, InetAddressException, InterruptedException { + public void TestV4Only() throws IOException, XdbException, InetAddressException, InterruptedException, InvalidConfigException { final Config v4Config = Config.custom() .setCachePolicy(Config.NoCache) .setXdbPath(ConfigTest.getDataPath("ip2region_v4.xdb")) diff --git a/binding/java/src/test/java/org/lionsoul/ip2region/service/SearcherPoolTest.java b/binding/java/src/test/java/org/lionsoul/ip2region/service/SearcherPoolTest.java index 5d07761..5c32f63 100644 --- a/binding/java/src/test/java/org/lionsoul/ip2region/service/SearcherPoolTest.java +++ b/binding/java/src/test/java/org/lionsoul/ip2region/service/SearcherPoolTest.java @@ -32,6 +32,30 @@ public class SearcherPoolTest { log.debugf("v4 searcher pool closed gracefully"); } + @Test + public void testInMemV4SearcherPool() throws Exception { + final Config v4Config = Config.custom() + .setCachePolicy(Config.FullCache) + .setSearchers(5) + .setXdbPath(ConfigTest.getDataPath("ip2region_v4.xdb")) + .asV4(); + + + final String ipStr = "58.250.36.41"; + final SearcherPool v4Pool = SearcherPool.create(v4Config); + for (int i = 0; i < 20; i++) { + final Searcher searcher = v4Pool.borrowSearcher(); + log.debugf("borrowed searcher %d: %s", i, searcher.toString()); + final String region = searcher.search(ipStr); + log.debugf("search(%s)=%s", ipStr, region); + v4Pool.returnSearcher(searcher); + log.debugf("return searcher %d", i); + } + + v4Pool.close(); + log.debugf("v4 searcher pool closed gracefully"); + } + @Test public void testV6SearcherPool() throws Exception { final Config v6Config = Config.custom()