diff --git a/binding/java/ReadMe.md b/binding/java/ReadMe.md index 8327ad2..363fbe0 100644 --- a/binding/java/ReadMe.md +++ b/binding/java/ReadMe.md @@ -7,7 +7,7 @@ org.lionsoul ip2region - 3.2.2 + 3.3.0 ``` @@ -247,40 +247,45 @@ mvn compile package # 查询测试 -可以通过 `java -jar ip2region-{version}.jar search` 命令来测试查询: +### 测试命令 +可以通过 `java -jar target/ip2region-{version}.jar search` 命令来测试查询: ```bash -➜ java git:(fr_java_ipv6) ✗ java -jar target/ip2region-3.1.0.jar search +➜ java git:(master) ✗ java -jar target/ip2region-3.3.0.jar search --help java -jar ip2region-{version}.jar search [command options] options: - --db string ip2region binary xdb file path - --cache-policy string cache policy: file/vectorIndex/content + --v4-db string ip2region ipv4 binary xdb file path + --v4-cache-policy string v4 cache policy, default vectorIndex, options: file/vectorIndex/content + --v6-db string ip2region ipv6 binary xdb file path + --v6-cache-policy string v6 cache policy, default vectorIndex, options: file/vectorIndex/content + --help print this help menu ``` -例如:使用默认的 data/ip2region_v4.xdb 文件进行 IPv4 的查询测试: +### 参数解析 +1. `v4-xdb`: IPv4 的 xdb 文件路径,默认为仓库中的 data/ip2region_v4.xdb +2. `v6-xdb`: IPv6 的 xdb 文件路径,默认为仓库中的 data/ip2region_v6.xdb +3. `v4-cache-policy`: v4 查询使用的缓存策略,默认为 `vectorIndex`,可选:file/vectorIndex/content +4. `v6-cache-policy`: v6 查询使用的缓存策略,默认为 `vectorIndex`,可选:file/vectorIndex/content + +### 测试 Demo +例如:使用默认的 data/ip2region_v4.xdb 和 data/ip2region_v6.xdb 进行查询测试: ```bash -➜ java git:(fr_java_ipv6) ✗ java -jar target/ip2region-3.1.0.jar search --db=../../data/ip2region_v4.xdb -ip2region xdb searcher test program -source xdb: ../../data/ip2region_v4.xdb (IPv4, vectorIndex) +➜ java git:(java_app_with_ip2region_service) ✗ java -jar target/ip2region-3.3.0.jar search +ip2region search service test program ++-v4 xdb: /data01/code/c/ip2region/data/ip2region_v4.xdb (vectorIndex) ++-v6 xdb: /data01/code/c/ip2region/data/ip2region_v6.xdb (vectorIndex) type 'quit' to exit ip2region>> 1.2.3.4 -{region: 美国|华盛顿|0|谷歌, ioCount: 7, took: 82 μs} +{region: 美国|华盛顿|0|谷歌, took: 159 μs} +ip2region>> 240e:3b7:3272:d8d0:db09:c067:8d59:539e +{region: 中国|广东省|深圳市|家庭宽带, took: 346 μs} +ip2region>> ``` - -例如:使用默认的 data/ip2region_v6.xdb 文件进行 IPv6 的查询测试: -```bash -➜ java git:(fr_java_ipv6) ✗ java -jar target/ip2region-3.1.0.jar search --db=../../data/ip2region_v6.xdb -ip2region xdb searcher test program -source xdb: ../../data/ip2region_v6.xdb (IPv6, vectorIndex) -type 'quit' to exit -ip2region>> 240e:3b7:3272:d8d0:db09:c067:8d59:539e -{region: 中国|广东省|深圳市|家庭宽带, ioCount: 14, took: 424 μs} -``` - -输入 ip 即可进行查询测试,也可以分别设置 `cache-policy` 为 file/vectorIndex/content 来测试三种不同缓存实现的查询效果。 +输入 v4 或者 v6 的 IP 地址即可进行查询测试,也可以分别设置 `cache-policy` 为 file/vectorIndex/content 来测试三种不同缓存实现的查询效果。 # bench 测试 +### 测试命令 可以通过 `java -jar ip2region-{version}.jar bench` 命令来进行 bench 测试,一方面确保 `xdb` 文件没有错误,一方面可以评估查询性能: ```bash ➜ java git:(fr_java_ipv6) ✗ java -jar target/ip2region-3.1.0.jar bench @@ -291,11 +296,13 @@ options: --cache-policy string cache policy: file/vectorIndex/content ``` +### v4 bench 例如:通过默认的 data/ip2region_v4.xdb 和 data/ipv4_source.txt 文件进行 IPv4 的 bench 测试: ```bash java -jar target/ip2region-3.1.0.jar bench --db=../../data/ip2region_v4.xdb --src=../../data/ipv4_source.txt ``` +### v6 bench 例如:通过默认的 data/ip2region_v6.xdb 和 data/ipv6_source.txt 文件进行 IPv6 的 bench 测试: ```bash java -jar target/ip2region-3.1.0.jar bench --db=../../data/ip2region_v6.xdb --src=../../data/ipv6_source.txt diff --git a/binding/java/pom.xml b/binding/java/pom.xml index 35f74b1..ce1b62d 100644 --- a/binding/java/pom.xml +++ b/binding/java/pom.xml @@ -4,7 +4,7 @@ org.lionsoul ip2region - 3.2.2 + 3.3.0 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 448f3b5..279160f 100644 --- a/binding/java/src/main/java/org/lionsoul/ip2region/SearcherTest.java +++ b/binding/java/src/main/java/org/lionsoul/ip2region/SearcherTest.java @@ -6,6 +6,9 @@ package org.lionsoul.ip2region; +import org.lionsoul.ip2region.service.Config; +import org.lionsoul.ip2region.service.InvalidCachePolicyException; +import org.lionsoul.ip2region.service.Ip2Region; import org.lionsoul.ip2region.xdb.InetAddressException; import org.lionsoul.ip2region.xdb.XdbException; import org.lionsoul.ip2region.xdb.LongByteArray; @@ -15,6 +18,9 @@ import org.lionsoul.ip2region.xdb.Version; import java.io.*; import java.nio.charset.Charset; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.CodeSource; import java.util.concurrent.TimeUnit; public class SearcherTest { @@ -27,6 +33,36 @@ public class SearcherTest { System.out.print(" bench search bench test\n"); } + public static final String getXdbPath(String fileName) throws IOException { + String xdbPath; + final CodeSource cs = SearcherTest.class.getProtectionDomain().getCodeSource(); + if (cs != null) { + // log.debugf("code path: %s", cs.getLocation().getPath().concat("../../../../data/")); + final Path jarPath = Paths.get(cs.getLocation().getPath()); + xdbPath = jarPath.getParent().toString().concat("/../../../data/").concat(fileName); + } else { + xdbPath = "../../../data/".concat(fileName); + } + + final File xdbFile = new File(xdbPath); + return xdbFile.exists() ? xdbFile.getCanonicalPath() : ""; + } + + public static final Ip2Region createService( + String v4XdbPath, String v4CachePolicy, String v6XdbPath, String v6CachePolicy) throws IOException, XdbException, InvalidCachePolicyException { + final Config v4Config = Config.custom() + .setCachePolicy(Config.cachePolicyFromName(v4CachePolicy)) + .setSearchers(1) + .setXdbPath(v4XdbPath).asV4(); + + final Config v6Config = Config.custom() + .setCachePolicy(Config.cachePolicyFromName(v6CachePolicy)) + .setSearchers(1) + .setXdbPath(v6XdbPath).asV6(); + + return Ip2Region.create(v4Config, v6Config); + } + public static Searcher createSearcher(String dbPath, String cachePolicy) throws IOException, XdbException { final RandomAccessFile handle = new RandomAccessFile(dbPath, "r"); @@ -43,18 +79,20 @@ public class SearcherTest { if ("file".equals(cachePolicy)) { return Searcher.newWithFileOnly(version, dbPath); } else if ("vectorIndex".equals(cachePolicy)) { - byte[] vIndex = Searcher.loadVectorIndexFromFile(dbPath); + final byte[] vIndex = Searcher.loadVectorIndexFromFile(dbPath); return Searcher.newWithVectorIndex(version, dbPath, vIndex); } else if ("content".equals(cachePolicy)) { - LongByteArray cBuff = Searcher.loadContentFromFile(dbPath); + final LongByteArray cBuff = Searcher.loadContentFromFile(dbPath); return Searcher.newWithBuffer(version, cBuff); } else { throw new IOException("invalid cache policy `" + cachePolicy + "`, options: file/vectorIndex/content"); } } - public static void searchTest(String[] args) throws IOException, XdbException { - String dbPath = "", cachePolicy = "vectorIndex"; + public static void searchTest(String[] args) throws IOException, XdbException, InvalidCachePolicyException, InterruptedException { + String help = ""; + String v4DbPath = "", v4CachePolicy = "vectorIndex"; + String v6DbPath = "", v6CachePolicy = "vectorIndex"; for (final String r : args) { if (r.length() < 5) { continue; @@ -64,38 +102,62 @@ public class SearcherTest { continue; } + String key = "", val = ""; int sIdx = r.indexOf('='); if (sIdx < 0) { - System.out.printf("missing = for args pair `%s`\n", r); - return; + key = r.substring(2); + // System.out.printf("missing = for args pair `%s`\n", r); + // return; + } else { + key = r.substring(2, sIdx); + val = r.substring(sIdx + 1); } - String key = r.substring(2, sIdx); - String val = r.substring(sIdx + 1); // System.out.printf("key=%s, val=%s\n", key, val); - if ("db".equals(key)) { - dbPath = val; - } else if ("cache-policy".equals(key)) { - cachePolicy = val; + if ("help".equals(key)) { + help = val == "" ? "true" : val; + } else if ("v4-db".equals(key)) { + v4DbPath = val; + } else if ("v4-cache-policy".equals(key)) { + v4CachePolicy = val; + } else if ("v6-db".equals(key)) { + v6DbPath = val; + } else if ("v6-cache-policy".equals(key)) { + v6CachePolicy = val; } else { System.out.printf("undefined option `%s`\n", r); return; } } - if (dbPath.isEmpty()) { + + // check and set the default path for v4 + if (v4DbPath.isEmpty()) { + v4DbPath = getXdbPath("ip2region_v4.xdb"); + } + + // check and set the default path for 6 + if (v6DbPath.isEmpty()) { + v6DbPath = getXdbPath("ip2region_v6.xdb"); + } + + if (v4DbPath.isEmpty() || v6DbPath.isEmpty() || help.equals("true")) { System.out.print("java -jar ip2region-{version}.jar search [command options]\n"); System.out.print("options:\n"); - System.out.print(" --db string ip2region binary xdb file path\n"); - System.out.print(" --cache-policy string cache policy: file/vectorIndex/content\n"); + System.out.print(" --v4-db string ip2region ipv4 binary xdb file path\n"); + System.out.print(" --v4-cache-policy string v4 cache policy, default vectorIndex, options: file/vectorIndex/content\n"); + System.out.print(" --v6-db string ip2region ipv6 binary xdb file path\n"); + System.out.print(" --v6-cache-policy string v6 cache policy, default vectorIndex, options: file/vectorIndex/content\n"); + System.out.print(" --help print this help menu\n"); return; } - Searcher searcher = createSearcher(dbPath, cachePolicy); + final Ip2Region ip2region = createService(v4DbPath, v4CachePolicy, v6DbPath, v6CachePolicy); final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); - System.out.printf("ip2region xdb searcher test program\n" -+ "source xdb: %s (%s, %s)\n" -+ "type 'quit' to exit\n", dbPath, searcher.getIPVersion().name, cachePolicy); + System.out.printf("ip2region search service test program\n" ++ "+-v4 xdb: %s (%s)\n" ++ "+-v6 xdb: %s (%s)\n" ++ "type 'quit' to exit\n", v4DbPath, v4CachePolicy, v6DbPath, v6CachePolicy); while ( true ) { System.out.print("ip2region>> "); String line = reader.readLine().trim(); @@ -109,17 +171,17 @@ public class SearcherTest { try { double sTime = System.nanoTime(); - String region = searcher.search(line); + String region = ip2region.search(line); long cost = TimeUnit.NANOSECONDS.toMicros((long) (System.nanoTime() - sTime)); - System.out.printf("{region: %s, ioCount: %d, took: %d μs}\n", region, searcher.getIOCount(), cost); + System.out.printf("{region: %s, took: %d μs}\n", region, cost); } catch (Exception e) { - System.out.printf("{err: %s, ioCount: %d}\n", e, searcher.getIOCount()); + System.out.printf("{region: , err: %s}\n", e); } } reader.close(); - searcher.close(); - System.out.println("searcher test program exited, thanks for trying"); + ip2region.close(); + System.out.println("ip2region test program exited, thanks for trying"); } public static void benchTest(String[] args) throws IOException, XdbException, InetAddressException { 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 96babb6..8e8388b 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 @@ -1,6 +1,7 @@ // 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; import java.io.IOException; @@ -80,4 +81,17 @@ public class Config { sb.append('}'); return sb.toString(); } + + public static final int cachePolicyFromName(String name) throws InvalidCachePolicyException { + final String lName = name.toLowerCase(); + if (lName.equals("file") || lName.equals("nocache")) { + return NoCache; + } else if (lName.equals("vectorindex") || lName.equals("vindex") || lName.equals("vindexcache")) { + return VIndexCache; + } else if (lName.equals("content") || lName.equals("buffercache")) { + return BufferCache; + } else { + throw new InvalidCachePolicyException("invalid cache policy `" + name + "`"); + } + } } \ No newline at end of file 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 new file mode 100644 index 0000000..348e58f --- /dev/null +++ b/binding/java/src/main/java/org/lionsoul/ip2region/service/InvalidCachePolicyException.java @@ -0,0 +1,11 @@ +// 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); + } +}