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);
+ }
+}