From 7385fe937dda04b4bd386aee613d52bb144ccfa2 Mon Sep 17 00:00:00 2001 From: Looly Date: Sun, 27 Mar 2022 21:15:49 +0800 Subject: [PATCH] add FuncFilter --- CHANGELOG.md | 3 +- .../bloomfilter/filter/AbstractFilter.java | 8 ++-- .../bloomfilter/filter/DefaultFilter.java | 13 ++---- .../hutool/bloomfilter/filter/ELFFilter.java | 14 ++----- .../hutool/bloomfilter/filter/FNVFilter.java | 14 ++----- .../hutool/bloomfilter/filter/FuncFilter.java | 42 +++++++++++++++++++ .../hutool/bloomfilter/filter/HfFilter.java | 27 +++--------- .../hutool/bloomfilter/filter/HfIpFilter.java | 21 +++------- .../hutool/bloomfilter/filter/JSFilter.java | 25 +++-------- .../hutool/bloomfilter/filter/PJWFilter.java | 14 ++----- .../hutool/bloomfilter/filter/RSFilter.java | 14 ++----- .../hutool/bloomfilter/filter/SDBMFilter.java | 14 ++----- .../bloomfilter/filter/TianlFilter.java | 15 ++----- .../java/cn/hutool/core/util/HashUtil.java | 42 ++++++++++++++++++- 14 files changed, 134 insertions(+), 132 deletions(-) create mode 100644 hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/FuncFilter.java diff --git a/CHANGELOG.md b/CHANGELOG.md index be4b453ca..fdcc65b2e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ # 🚀Changelog ------------------------------------------------------------------------------------------------------------- -# 5.8.0 (2022-03-26) +# 5.8.0 (2022-03-27) ### ❌不兼容特性 * 【db 】 【不向下兼容 】增加MongoDB4.x支持返回MongoClient变更(pr#568@Gitee) @@ -46,6 +46,7 @@ * 【core 】 CompareUtil增加comparingIndexed(pr#585@Gitee) * 【db 】 DruidDataSource构建时支持自定义参数(issue#I4ZKCW@Gitee) * 【poi 】 ExcelWriter增加addImg重载(issue#2218@Github) +* 【bloomFilter】 增加FuncFilter ### 🐞Bug修复 * 【core 】 修复ObjectUtil.hasNull传入null返回true的问题(pr#555@Gitee) diff --git a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/AbstractFilter.java b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/AbstractFilter.java index a19d55527..bc37e729d 100644 --- a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/AbstractFilter.java +++ b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/AbstractFilter.java @@ -14,9 +14,11 @@ import cn.hutool.bloomfilter.bitMap.LongMap; public abstract class AbstractFilter implements BloomFilter { private static final long serialVersionUID = 1L; + protected static int DEFAULT_MACHINE_NUM = BitMap.MACHINE32; + private BitMap bm = null; - protected long size = 0; + protected long size; /** * 构造 @@ -34,7 +36,7 @@ public abstract class AbstractFilter implements BloomFilter { * @param maxValue 最大值 */ public AbstractFilter(long maxValue) { - this(maxValue, BitMap.MACHINE32); + this(maxValue, DEFAULT_MACHINE_NUM); } /** @@ -80,4 +82,4 @@ public abstract class AbstractFilter implements BloomFilter { * @return HashCode */ public abstract long hash(String str); -} \ No newline at end of file +} diff --git a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/DefaultFilter.java b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/DefaultFilter.java index 0543d0722..2f1ef0309 100644 --- a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/DefaultFilter.java +++ b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/DefaultFilter.java @@ -7,19 +7,14 @@ import cn.hutool.core.util.HashUtil; * * @author loolly */ -public class DefaultFilter extends AbstractFilter { +public class DefaultFilter extends FuncFilter { private static final long serialVersionUID = 1L; - public DefaultFilter(long maxValue, int machineNumber) { - super(maxValue, machineNumber); - } - public DefaultFilter(long maxValue) { - super(maxValue); + this(maxValue, DEFAULT_MACHINE_NUM); } - @Override - public long hash(String str) { - return HashUtil.javaDefaultHash(str) % size; + public DefaultFilter(long maxValue, int machineNumber) { + super(maxValue, machineNumber, HashUtil::javaDefaultHash); } } diff --git a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/ELFFilter.java b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/ELFFilter.java index 81c44a37f..983040c3e 100644 --- a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/ELFFilter.java +++ b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/ELFFilter.java @@ -2,20 +2,14 @@ package cn.hutool.bloomfilter.filter; import cn.hutool.core.util.HashUtil; -public class ELFFilter extends AbstractFilter { +public class ELFFilter extends FuncFilter { private static final long serialVersionUID = 1L; - public ELFFilter(long maxValue, int machineNumber) { - super(maxValue, machineNumber); - } - public ELFFilter(long maxValue) { - super(maxValue); + this(maxValue, DEFAULT_MACHINE_NUM); } - @Override - public long hash(String str) { - return HashUtil.elfHash(str) % size; + public ELFFilter(long maxValue, int machineNumber) { + super(maxValue, machineNumber, HashUtil::elfHash); } - } diff --git a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/FNVFilter.java b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/FNVFilter.java index 4f7384bfb..7e71e3ce3 100644 --- a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/FNVFilter.java +++ b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/FNVFilter.java @@ -2,20 +2,14 @@ package cn.hutool.bloomfilter.filter; import cn.hutool.core.util.HashUtil; -public class FNVFilter extends AbstractFilter { +public class FNVFilter extends FuncFilter { private static final long serialVersionUID = 1L; - public FNVFilter(long maxValue, int machineNum) { - super(maxValue, machineNum); - } - public FNVFilter(long maxValue) { - super(maxValue); + this(maxValue, DEFAULT_MACHINE_NUM); } - @Override - public long hash(String str) { - return HashUtil.fnvHash(str); + public FNVFilter(long maxValue, int machineNum) { + super(maxValue, machineNum, HashUtil::fnvHash); } - } diff --git a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/FuncFilter.java b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/FuncFilter.java new file mode 100644 index 000000000..7830eebca --- /dev/null +++ b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/FuncFilter.java @@ -0,0 +1,42 @@ +package cn.hutool.bloomfilter.filter; + +import cn.hutool.bloomfilter.BloomFilter; + +import java.util.function.Function; + +/** + * 基于Hash函数方法的{@link BloomFilter} + * + * @author looly + * @since 5.8.0 + */ +public class FuncFilter extends AbstractFilter { + private static final long serialVersionUID = 1L; + + private final Function hashFunc; + + /** + * 构造 + * + * @param maxValue 最大值 + * @param hashFunc Hash函数 + */ + public FuncFilter(long maxValue, Function hashFunc) { + this(maxValue, DEFAULT_MACHINE_NUM, hashFunc); + } + + /** + * @param maxValue 最大值 + * @param machineNum 机器位数 + * @param hashFunc Hash函数 + */ + public FuncFilter(long maxValue, int machineNum, Function hashFunc) { + super(maxValue, machineNum); + this.hashFunc = hashFunc; + } + + @Override + public long hash(String str) { + return hashFunc.apply(str).longValue() % size; + } +} diff --git a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/HfFilter.java b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/HfFilter.java index fc2814149..19158406b 100644 --- a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/HfFilter.java +++ b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/HfFilter.java @@ -1,31 +1,16 @@ package cn.hutool.bloomfilter.filter; -public class HfFilter extends AbstractFilter { +import cn.hutool.core.util.HashUtil; + +public class HfFilter extends FuncFilter { private static final long serialVersionUID = 1L; - public HfFilter(long maxValue, int machineNum) { - super(maxValue, machineNum); - } - public HfFilter(long maxValue) { - super(maxValue); + this(maxValue, DEFAULT_MACHINE_NUM); } - @Override - public long hash(String str) { - int length = str.length() ; - long hash = 0; - - for (int i = 0; i < length; i++) { - hash += str.charAt(i) * 3 * i; - } - - if (hash < 0) { - hash = -hash; - } - - return hash % size; + public HfFilter(long maxValue, int machineNum) { + super(maxValue, machineNum, HashUtil::hfHash); } - } diff --git a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/HfIpFilter.java b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/HfIpFilter.java index d02097560..e8f64cb4e 100644 --- a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/HfIpFilter.java +++ b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/HfIpFilter.java @@ -1,24 +1,15 @@ package cn.hutool.bloomfilter.filter; -public class HfIpFilter extends AbstractFilter { +import cn.hutool.core.util.HashUtil; + +public class HfIpFilter extends FuncFilter { private static final long serialVersionUID = 1L; - public HfIpFilter(long maxValue, int machineNum) { - super(maxValue, machineNum); - } - public HfIpFilter(long maxValue) { - super(maxValue); + this(maxValue, DEFAULT_MACHINE_NUM); } - @Override - public long hash(String str) { - int length = str.length(); - long hash = 0; - for (int i = 0; i < length; i++) { - hash += str.charAt(i % 4) ^ str.charAt(i); - } - return hash % size; + public HfIpFilter(long maxValue, int machineNum) { + super(maxValue, machineNum, HashUtil::hfIpHash); } - } diff --git a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/JSFilter.java b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/JSFilter.java index af9d5837f..42fd83866 100644 --- a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/JSFilter.java +++ b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/JSFilter.java @@ -1,30 +1,15 @@ package cn.hutool.bloomfilter.filter; +import cn.hutool.core.util.HashUtil; -public class JSFilter extends AbstractFilter { +public class JSFilter extends FuncFilter { private static final long serialVersionUID = 1L; - public JSFilter(long maxValue, int machineNum) { - super(maxValue, machineNum); - } - public JSFilter(long maxValue) { - super(maxValue); + this(maxValue, DEFAULT_MACHINE_NUM); } - @Override - public long hash(String str) { - int hash = 1315423911; - - for (int i = 0; i < str.length(); i++) { - hash ^= ((hash << 5) + str.charAt(i) + (hash >> 2)); - } - - if(hash<0) { - hash*=-1 ; - } - - return hash % size; + public JSFilter(long maxValue, int machineNum) { + super(maxValue, machineNum, HashUtil::jsHash); } - } diff --git a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/PJWFilter.java b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/PJWFilter.java index 62e8006f3..f9788d481 100644 --- a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/PJWFilter.java +++ b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/PJWFilter.java @@ -2,20 +2,14 @@ package cn.hutool.bloomfilter.filter; import cn.hutool.core.util.HashUtil; -public class PJWFilter extends AbstractFilter { +public class PJWFilter extends FuncFilter { private static final long serialVersionUID = 1L; - public PJWFilter(long maxValue, int machineNum) { - super(maxValue, machineNum); - } - public PJWFilter(long maxValue) { - super(maxValue); + this(maxValue, DEFAULT_MACHINE_NUM); } - @Override - public long hash(String str) { - return HashUtil.pjwHash(str) % size; + public PJWFilter(long maxValue, int machineNum) { + super(maxValue, machineNum, HashUtil::pjwHash); } - } diff --git a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/RSFilter.java b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/RSFilter.java index f84dadaae..5ce961e3b 100644 --- a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/RSFilter.java +++ b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/RSFilter.java @@ -2,20 +2,14 @@ package cn.hutool.bloomfilter.filter; import cn.hutool.core.util.HashUtil; -public class RSFilter extends AbstractFilter { +public class RSFilter extends FuncFilter { private static final long serialVersionUID = 1L; - public RSFilter(long maxValue, int machineNum) { - super(maxValue, machineNum); - } - public RSFilter(long maxValue) { - super(maxValue); + this(maxValue, DEFAULT_MACHINE_NUM); } - @Override - public long hash(String str) { - return HashUtil.rsHash(str) % size; + public RSFilter(long maxValue, int machineNum) { + super(maxValue, machineNum, HashUtil::rsHash); } - } diff --git a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/SDBMFilter.java b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/SDBMFilter.java index 78c3f696c..6cd258af1 100644 --- a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/SDBMFilter.java +++ b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/SDBMFilter.java @@ -2,20 +2,14 @@ package cn.hutool.bloomfilter.filter; import cn.hutool.core.util.HashUtil; -public class SDBMFilter extends AbstractFilter { +public class SDBMFilter extends FuncFilter { private static final long serialVersionUID = 1L; - public SDBMFilter(long maxValue, int machineNum) { - super(maxValue, machineNum); - } - public SDBMFilter(long maxValue) { - super(maxValue); + this(maxValue, DEFAULT_MACHINE_NUM); } - @Override - public long hash(String str) { - return HashUtil.sdbmHash(str) % size; + public SDBMFilter(long maxValue, int machineNum) { + super(maxValue, machineNum, HashUtil::sdbmHash); } - } diff --git a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/TianlFilter.java b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/TianlFilter.java index 0810e2604..7ea98e6de 100644 --- a/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/TianlFilter.java +++ b/hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/filter/TianlFilter.java @@ -2,21 +2,14 @@ package cn.hutool.bloomfilter.filter; import cn.hutool.core.util.HashUtil; - -public class TianlFilter extends AbstractFilter { +public class TianlFilter extends FuncFilter { private static final long serialVersionUID = 1L; - public TianlFilter(long maxValue, int machineNum) { - super(maxValue, machineNum); - } - public TianlFilter(long maxValue) { - super(maxValue); + this(maxValue, DEFAULT_MACHINE_NUM); } - @Override - public long hash(String str) { - return HashUtil.tianlHash(str) % size; + public TianlFilter(long maxValue, int machineNum) { + super(maxValue, machineNum, HashUtil::tianlHash); } - } diff --git a/hutool-core/src/main/java/cn/hutool/core/util/HashUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/HashUtil.java index bafe37995..e5045601e 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/HashUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/HashUtil.java @@ -226,7 +226,7 @@ public class HashUtil { hash ^= ((hash << 5) + str.charAt(i) + (hash >> 2)); } - return hash & 0x7FFFFFFF; + return Math.abs(hash) & 0x7FFFFFFF; } /** @@ -576,7 +576,7 @@ public class HashUtil { * @return hash值,long[0]:低位,long[1]:高位 */ public static long[] metroHash128(byte[] data, long seed) { - return MetroHash.hash128(data,seed).getLongArray(); + return MetroHash.hash128(data, seed).getLongArray(); } /** @@ -588,4 +588,42 @@ public class HashUtil { public static long[] metroHash128(byte[] data) { return MetroHash.hash128(data).getLongArray(); } + + /** + * HF Hash算法 + * + * @param data 字符串 + * @return hash结果 + * @since 5.8.0 + */ + public static long hfHash(String data) { + int length = data.length(); + long hash = 0; + + for (int i = 0; i < length; i++) { + hash += (long) data.charAt(i) * 3 * i; + } + + if (hash < 0) { + hash = -hash; + } + + return hash; + } + + /** + * HFIP Hash算法 + * + * @param data 字符串 + * @return hash结果 + * @since 5.8.0 + */ + public static long hfIpHash(String data) { + int length = data.length(); + long hash = 0; + for (int i = 0; i < length; i++) { + hash += data.charAt(i % 4) ^ data.charAt(i); + } + return hash; + } }