diff --git a/binding/java/src/main/java/org/lionsoul/ip2region/Ip2Region.java b/binding/java/src/main/java/org/lionsoul/ip2region/Ip2Region.java index b5c116c..0a41282 100644 --- a/binding/java/src/main/java/org/lionsoul/ip2region/Ip2Region.java +++ b/binding/java/src/main/java/org/lionsoul/ip2region/Ip2Region.java @@ -9,6 +9,7 @@ import java.io.IOException; import org.lionsoul.ip2region.xdb.InetAddressException; import org.lionsoul.ip2region.xdb.Searcher; import org.lionsoul.ip2region.xdb.Util; +import org.lionsoul.ip2region.xdb.XdbException; /** * ip2region searcher manager service to provider: @@ -20,15 +21,66 @@ import org.lionsoul.ip2region.xdb.Util; */ public class Ip2Region { - /* v4 pool */ + /* v4 pool for cache policy vIndex or NoCache */ private final SearcherPool v4Pool; - /* v6 pool */ + /* v4 xdb searcher for cache policy cBuffer */ + private final Searcher v4InMemSearcher; + + /* v6 pool for cache policy vIndex or NoCache*/ private final SearcherPool v6Pool; + /* v6 xdb searcher for cache policy cBuffer */ + private final Searcher v6InMemSearcher; + + /** + * 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 + * @throws XdbException + * @throws IOException + */ + public Ip2Region(String v4XdbPath, String v6XdbPath) throws IOException, XdbException { + this( + v4XdbPath == null ? null : Config.custom().setXdbPath(v4XdbPath).asV4(), + v6XdbPath == null ? null : Config.custom().setXdbPath(v6XdbPath).asV6() + ); + } + + /** + * init the ip2region with specified config. + * set it to null for disabled the search for specified version + * + * @param v4Config + * @param v6Config + * @throws IOException + */ public Ip2Region(Config v4Config, Config v6Config) throws IOException { - this.v4Pool = new SearcherPool(v4Config); - this.v6Pool = new SearcherPool(v6Config); + if (v4Config == null) { + // @Note: with IPv4 disabled ? + this.v4InMemSearcher = null; + this.v4Pool = null; + } else if (v4Config.cachePolicy == Config.BufferCache) { + this.v4InMemSearcher = Searcher.newWithBuffer(v4Config.ipVersion, v4Config.cBuffer); + this.v4Pool = null; + } else { + this.v4InMemSearcher = null; + this.v4Pool = new SearcherPool(v4Config); + } + + if (v6Config == null) { + // @Note: with IPv6 disabled ? + this.v6InMemSearcher = null; + this.v6Pool = null; + } else if (v6Config.cachePolicy == Config.BufferCache) { + this.v6InMemSearcher = Searcher.newWithBuffer(v6Config.ipVersion, v6Config.cBuffer); + this.v6Pool = null; + } else { + this.v6InMemSearcher = null; + this.v6Pool = new SearcherPool(v6Config); + } } public String search(String ipString) throws InetAddressException, IOException, InterruptedException { @@ -36,24 +88,62 @@ public class Ip2Region { } public String search(byte[] ipBytes) throws InetAddressException, IOException, InterruptedException { - // 1, define the pool with the input ip - final SearcherPool pool; if (ipBytes.length == 4) { - pool = v4Pool; + return v4Search(ipBytes); } else if (ipBytes.length == 16) { - pool = v6Pool; + return v6Search(ipBytes); } else { throw new InetAddressException("invalid byte ip address with length=" + ipBytes.length); } + } - // 2, get a searcher from the pool - final Searcher searcher = pool.borrowSearcher(); + protected String v4Search(final byte[] ipBytes) throws IOException, InetAddressException, InterruptedException { + if (v4InMemSearcher != null) { + return v4InMemSearcher.search(ipBytes); + } + // IPv4 search is disabled + if (v4Pool == null) { + return null; + } + + final Searcher searcher = v4Pool.borrowSearcher(); try { - // 3, do the search return searcher.search(ipBytes); } finally { - pool.returnSearcher(searcher); + v4Pool.returnSearcher(searcher); + } + } + + protected String v6Search(final byte[] ipBytes) throws IOException, InetAddressException, InterruptedException { + if (v6InMemSearcher != null) { + return v6InMemSearcher.search(ipBytes); + } + + // IPv6 search is disabled + if (v6Pool == null) { + return null; + } + + final Searcher searcher = v6Pool.borrowSearcher(); + try { + return searcher.search(ipBytes); + } finally { + v6Pool.returnSearcher(searcher); + } + } + + public void close() throws InterruptedException { + close(10000); + } + + public void close(long timeoutMillis) throws InterruptedException { + if (v4Pool != null) { + v4Pool.close(timeoutMillis); + } + + if (v6Pool != null) { + v6Pool.close(timeoutMillis); } } diff --git a/binding/java/src/main/java/org/lionsoul/ip2region/SearcherPool.java b/binding/java/src/main/java/org/lionsoul/ip2region/SearcherPool.java index 6f362b8..d5167be 100644 --- a/binding/java/src/main/java/org/lionsoul/ip2region/SearcherPool.java +++ b/binding/java/src/main/java/org/lionsoul/ip2region/SearcherPool.java @@ -94,10 +94,14 @@ public class SearcherPool { // close the searcher pool public void close() throws InterruptedException { + close(10000); + } + + public void close(long timeoutMillis) throws InterruptedException { lock.lock(); try { while (loanCount > 0) { - fullCondition.wait(); + fullCondition.wait(timeoutMillis); } final Iterator it = pool.iterator(); 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 5664012..178e070 100644 --- a/binding/java/src/test/java/org/lionsoul/ip2region/ConfigTest.java +++ b/binding/java/src/test/java/org/lionsoul/ip2region/ConfigTest.java @@ -10,8 +10,8 @@ public class ConfigTest { private static final Log log = Log.getLogger(ConfigTest.class).setLevel(Log.DEBUG); - public String getDataPath(String xdbFile) { - final CodeSource cs = this.getClass().getProtectionDomain().getCodeSource(); + public static final String getDataPath(String xdbFile) { + final CodeSource cs = ConfigTest.class.getProtectionDomain().getCodeSource(); if (cs != null) { // log.debugf("code path: %s", cs.getLocation().getPath().concat("../../../../data/")); return cs.getLocation().getPath().concat("../../../../data/").concat(xdbFile); diff --git a/binding/java/src/test/java/org/lionsoul/ip2region/Ip2RegionTest.java b/binding/java/src/test/java/org/lionsoul/ip2region/Ip2RegionTest.java new file mode 100644 index 0000000..f77dd2a --- /dev/null +++ b/binding/java/src/test/java/org/lionsoul/ip2region/Ip2RegionTest.java @@ -0,0 +1,54 @@ +package org.lionsoul.ip2region; + +import java.io.IOException; + +import org.junit.Test; +import org.lionsoul.ip2region.xdb.InetAddressException; +import org.lionsoul.ip2region.xdb.Log; +import org.lionsoul.ip2region.xdb.Util; +import org.lionsoul.ip2region.xdb.XdbException; + +public class Ip2RegionTest { + + private static final Log log = Log.getLogger(Ip2RegionTest.class).setLevel(Log.DEBUG); + + @Test + public void TestConfigCreate() throws IOException, XdbException, InetAddressException, InterruptedException { + final Config v4Config = Config.custom() + .setCachePolicy(Config.NoCache) + .setSeachers(10) + .setXdbPath(ConfigTest.getDataPath("ip2region_v4.xdb")) + .asV4(); + + final Config v6Config = Config.custom() + .setCachePolicy(Config.VIndexCache) + .setSeachers(10) + .setXdbPath(ConfigTest.getDataPath("ip2region_v6.xdb")) + .asV6(); + + byte[] v4Bytes = Util.parseIP("1.2.3.4"); + byte[] v6Bytes = Util.parseIP("240e:3b7:3272:d8d0:db09:c067:8d59:539e"); + final Ip2Region ip2Region = new Ip2Region(v4Config, v6Config); + for (int i = 0; i < 50; i++) { + v4Bytes = Util.ipAddOne(v4Bytes); + v6Bytes = Util.ipAddOne(v6Bytes); + final String v4Region = ip2Region.search(v4Bytes); + final String v6Region = ip2Region.search(v6Bytes); + log.debugf("search(%s)=%s, search(%s)=%s", Util.ipToString(v4Bytes), v4Region, Util.ipToString(v6Bytes), v6Region); + } + + ip2Region.close(); + log.debugf("ip2region closed gracefully"); + } + + @Test + public void TestPathCreate() { + + } + + @Test + public void TestInMemSearch() { + + } + +} diff --git a/binding/java/src/test/java/org/lionsoul/ip2region/SearcherPoolTest.java b/binding/java/src/test/java/org/lionsoul/ip2region/SearcherPoolTest.java index ef51252..db80a7c 100644 --- a/binding/java/src/test/java/org/lionsoul/ip2region/SearcherPoolTest.java +++ b/binding/java/src/test/java/org/lionsoul/ip2region/SearcherPoolTest.java @@ -1,31 +1,19 @@ package org.lionsoul.ip2region; -import java.security.CodeSource; - import org.junit.Test; import org.lionsoul.ip2region.xdb.Log; import org.lionsoul.ip2region.xdb.Searcher; public class SearcherPoolTest { - private static final Log log = Log.getLogger(ConfigTest.class).setLevel(Log.DEBUG); - - public String getDataPath(String xdbFile) { - final CodeSource cs = this.getClass().getProtectionDomain().getCodeSource(); - if (cs != null) { - // log.debugf("code path: %s", cs.getLocation().getPath().concat("../../../../data/")); - return cs.getLocation().getPath().concat("../../../../data/").concat(xdbFile); - } else { - return "../../../../data/".concat(xdbFile); - } - } + private static final Log log = Log.getLogger(SearcherPoolTest.class).setLevel(Log.DEBUG); @Test public void testV4SeacherPool() throws Exception { final Config v4Config = Config.custom() .setCachePolicy(Config.VIndexCache) .setSeachers(5) - .setXdbPath(getDataPath("ip2region_v4.xdb")) + .setXdbPath(ConfigTest.getDataPath("ip2region_v4.xdb")) .asV4(); @@ -49,7 +37,7 @@ public class SearcherPoolTest { final Config v6Config = Config.custom() .setCachePolicy(Config.VIndexCache) .setSeachers(5) - .setXdbPath(getDataPath("ip2region_v6.xdb")) + .setXdbPath(ConfigTest.getDataPath("ip2region_v6.xdb")) .asV6();