diff --git a/binding/java/src/main/java/org/lionsoul/ip2region/Config.java b/binding/java/src/main/java/org/lionsoul/ip2region/Config.java index 64069f7..196c6a0 100644 --- a/binding/java/src/main/java/org/lionsoul/ip2region/Config.java +++ b/binding/java/src/main/java/org/lionsoul/ip2region/Config.java @@ -1,4 +1,4 @@ -// Copyright 2022 The Ip2Region Authors. All rights reserved. +// 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; @@ -29,7 +29,7 @@ public class Config { public final Header header; public final Version ipVersion; - // search limitation for NoCache or VIndexCache Only + // searcher pool limitation public final int minSearchers; public final int maxSearchers; @@ -38,18 +38,26 @@ public class Config { return new ConfigBuilder(); } - public Config(int cachePolicy, String xdbPath) throws IOException, XdbException { - this(cachePolicy, xdbPath, 10, 30); + public Config(int cachePolicy, Version ipVersion, String xdbPath) throws IOException, XdbException { + this(cachePolicy, ipVersion, xdbPath, 10, 50); } - public Config(int cachePolicy, String xdbPath, int minSearchers, int maxSearchers) throws IOException, XdbException { + public Config(int cachePolicy, Version ipVersion, String xdbPath, int minSearchers, int maxSearchers) throws IOException, XdbException { this.cachePolicy = cachePolicy; this.xdbPath = xdbPath; // load the header from the xdb path final Header header = Searcher.loadHeaderFromFile(xdbPath); this.header = header; - this.ipVersion = Version.fromHeader(header); + final Version xVersion = Version.fromHeader(header); + + // this.ipVersion = Version.fromHeader(header); + this.ipVersion = ipVersion; + + // 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"); + } this.minSearchers = minSearchers; this.maxSearchers = maxSearchers; @@ -67,4 +75,4 @@ public class Config { sb.append('}'); return sb.toString(); } -} +} \ No newline at end of file diff --git a/binding/java/src/main/java/org/lionsoul/ip2region/ConfigBuilder.java b/binding/java/src/main/java/org/lionsoul/ip2region/ConfigBuilder.java index c25f9c1..d0ee092 100644 --- a/binding/java/src/main/java/org/lionsoul/ip2region/ConfigBuilder.java +++ b/binding/java/src/main/java/org/lionsoul/ip2region/ConfigBuilder.java @@ -1,4 +1,4 @@ -// Copyright 2022 The Ip2Region Authors. All rights reserved. +// 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. @@ -6,6 +6,7 @@ package org.lionsoul.ip2region; import java.io.IOException; +import org.lionsoul.ip2region.xdb.Version; import org.lionsoul.ip2region.xdb.XdbException; /** @@ -17,7 +18,7 @@ public class ConfigBuilder { // cache policy private int cachePolicy = Config.VIndexCache; - + // xdb file path private String xdbPath = null; @@ -53,8 +54,14 @@ public class ConfigBuilder { return this; } - // build the final #Config instance with the current config items - public Config build() throws IOException, XdbException { - return new Config(cachePolicy, xdbPath, minSearchers, maxSearchers); + // build the final #Config instance for IPv4 + public Config asV4() throws IOException, XdbException { + return new Config(cachePolicy, Version.IPv4, xdbPath, minSearchers, maxSearchers); } + + // build the final #Config instance for IPv6 + public Config asV6() throws IOException, XdbException { + return new Config(cachePolicy, Version.IPv6, xdbPath, minSearchers, maxSearchers); + } + } \ No newline at end of file diff --git a/binding/java/src/main/java/org/lionsoul/ip2region/Ip2Region.java b/binding/java/src/main/java/org/lionsoul/ip2region/Ip2Region.java new file mode 100644 index 0000000..76dd3df --- /dev/null +++ b/binding/java/src/main/java/org/lionsoul/ip2region/Ip2Region.java @@ -0,0 +1,68 @@ +// 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; + +import java.io.IOException; + +import org.lionsoul.ip2region.xdb.InetAddressException; +import org.lionsoul.ip2region.xdb.Searcher; +import org.lionsoul.ip2region.xdb.Util; + +/** + * ip2region searcher manager service to provider: + * 1. Unified query interface for IPv4 and IPv6 address. + * 2. Concurrency search support. + * + * @Author Lion + * Date 2025/11/21 +*/ +public class Ip2Region { + + /* v4 pool */ + private final SearcherPool v4Pool; + + /* v6 pool */ + private final SearcherPool v6Pool; + + public Ip2Region(Config v4Config, Config v6Config) { + this.v4Pool = new SearcherPool(v4Config); + this.v6Pool = new SearcherPool(v6Config); + } + + public String search(String ipString) throws InetAddressException, IOException { + return search(Util.parseIP(ipString)); + } + + public String search(byte[] ipBytes) throws InetAddressException, IOException { + // 1, define the pool with the input ip + final SearcherPool pool; + if (ipBytes.length == 4) { + pool = v4Pool; + } else if (ipBytes.length == 16) { + pool = v6Pool; + } else { + throw new InetAddressException("invalid byte ip address with length=" + ipBytes.length); + } + + // 2, get a searcher from the pool + final Searcher searcher = pool.getSearcher(); + + try { + // 3, do the search + final String region = searcher.search(ipBytes); + return region; + } catch (InetAddressException e) { + // for the inet address error and we should return the searcher + throw e; + } catch (IOException e) { + // for the IOException usually means something is wrong with the read operation to the xdb file + // and we choose to keep the searcher and destory it right now + // so we will create a new one for the next search + try {searcher.close();} catch (IOException e1) {} + throw e; + } + } + +} \ No newline at end of file diff --git a/binding/java/src/main/java/org/lionsoul/ip2region/SearcherPool.java b/binding/java/src/main/java/org/lionsoul/ip2region/SearcherPool.java new file mode 100644 index 0000000..d2c90ea --- /dev/null +++ b/binding/java/src/main/java/org/lionsoul/ip2region/SearcherPool.java @@ -0,0 +1,33 @@ +// 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; + +import java.util.LinkedList; +import java.util.Queue; + +import org.lionsoul.ip2region.xdb.Searcher; + +/** + * ip2region searcher pool manager to provider Concurrency search support. + * + * @author Leon + * Date 2025/11/21 +*/ +public class SearcherPool { + // config instance + private final Config config; + + // searcher pool + private final Queue pool; + + public SearcherPool(Config config) { + this.config = config; + this.pool = new LinkedList<>(); + } + + public Searcher getSearcher() { + return null; + } +} \ No newline at end of file diff --git a/binding/java/src/test/java/org/lionsoul/ip2region/ConfigTest.java b/binding/java/src/test/java/org/lionsoul/ip2region/ConfigTest.java index 58e365e..c86b0d0 100644 --- a/binding/java/src/test/java/org/lionsoul/ip2region/ConfigTest.java +++ b/binding/java/src/test/java/org/lionsoul/ip2region/ConfigTest.java @@ -1,9 +1,10 @@ -package org.lionsoul.ip2region; +package org.lionsoul.ip2region; import java.io.IOException; import java.security.CodeSource; import org.junit.Test; import org.lionsoul.ip2region.xdb.Log; +import org.lionsoul.ip2region.xdb.Version; import org.lionsoul.ip2region.xdb.XdbException; public class ConfigTest { @@ -22,7 +23,7 @@ public class ConfigTest { @Test public void testConfig() throws IOException, XdbException { - final Config config = new Config(Config.VIndexCache, getDataPath("ip2region_v4.xdb"), 5, 10); + final Config config = new Config(Config.VIndexCache, Version.IPv4, getDataPath("ip2region_v4.xdb"), 5, 10); log.debugf("config: %s", config); } @@ -33,7 +34,7 @@ public class ConfigTest { .setXdbPath(getDataPath("ip2region_v6.xdb")) .setMinSearchers(10) .setMaxSearchers(30) - .build(); + .asV6(); log.debugf("builded config: %s", config); } -} +} \ No newline at end of file