Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ma yanling
hutool-5-master
Commits
45cda665
Commit
45cda665
authored
Sep 25, 2024
by
ma yanling
Browse files
project commit
parent
ad2fb30a
Pipeline
#2354
failed with stages
in 0 seconds
Changes
369
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
974 additions
and
0 deletions
+974
-0
hutool-aop/src/main/java/cn/hutool/aop/interceptor/SpringCglibInterceptor.java
...ava/cn/hutool/aop/interceptor/SpringCglibInterceptor.java
+65
-0
hutool-aop/src/main/java/cn/hutool/aop/interceptor/package-info.java
...src/main/java/cn/hutool/aop/interceptor/package-info.java
+7
-0
hutool-aop/src/main/java/cn/hutool/aop/package-info.java
hutool-aop/src/main/java/cn/hutool/aop/package-info.java
+7
-0
hutool-aop/src/main/java/cn/hutool/aop/proxy/CglibProxyFactory.java
.../src/main/java/cn/hutool/aop/proxy/CglibProxyFactory.java
+63
-0
hutool-aop/src/main/java/cn/hutool/aop/proxy/JdkProxyFactory.java
...op/src/main/java/cn/hutool/aop/proxy/JdkProxyFactory.java
+22
-0
hutool-aop/src/main/java/cn/hutool/aop/proxy/ProxyFactory.java
...l-aop/src/main/java/cn/hutool/aop/proxy/ProxyFactory.java
+73
-0
hutool-aop/src/main/java/cn/hutool/aop/proxy/SpringCglibProxyFactory.java
...ain/java/cn/hutool/aop/proxy/SpringCglibProxyFactory.java
+63
-0
hutool-aop/src/main/java/cn/hutool/aop/proxy/package-info.java
...l-aop/src/main/java/cn/hutool/aop/proxy/package-info.java
+7
-0
hutool-aop/src/main/resources/META-INF/services/cn.hutool.aop.proxy.ProxyFactory
...ources/META-INF/services/cn.hutool.aop.proxy.ProxyFactory
+3
-0
hutool-aop/src/test/java/cn/hutool/aop/test/AopTest.java
hutool-aop/src/test/java/cn/hutool/aop/test/AopTest.java
+88
-0
hutool-aop/src/test/java/cn/hutool/aop/test/IssueI74EX7Test.java
...aop/src/test/java/cn/hutool/aop/test/IssueI74EX7Test.java
+91
-0
hutool-bloomFilter/pom.xml
hutool-bloomFilter/pom.xml
+31
-0
hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/BitMapBloomFilter.java
...rc/main/java/cn/hutool/bloomfilter/BitMapBloomFilter.java
+82
-0
hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/BitSetBloomFilter.java
...rc/main/java/cn/hutool/bloomfilter/BitSetBloomFilter.java
+163
-0
hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/BloomFilter.java
...lter/src/main/java/cn/hutool/bloomfilter/BloomFilter.java
+29
-0
hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/BloomFilterUtil.java
.../src/main/java/cn/hutool/bloomfilter/BloomFilterUtil.java
+32
-0
hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/bitMap/BitMap.java
...er/src/main/java/cn/hutool/bloomfilter/bitMap/BitMap.java
+35
-0
hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/bitMap/IntMap.java
...er/src/main/java/cn/hutool/bloomfilter/bitMap/IntMap.java
+53
-0
hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/bitMap/LongMap.java
...r/src/main/java/cn/hutool/bloomfilter/bitMap/LongMap.java
+53
-0
hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/bitMap/package-info.java
.../main/java/cn/hutool/bloomfilter/bitMap/package-info.java
+7
-0
No files found.
Too many changes to show.
To preserve performance only
369 of 369+
files are displayed.
Plain diff
Email patch
hutool-aop/src/main/java/cn/hutool/aop/interceptor/SpringCglibInterceptor.java
0 → 100644
View file @
45cda665
package
cn.hutool.aop.interceptor
;
import
cn.hutool.aop.aspects.Aspect
;
import
org.springframework.cglib.proxy.MethodInterceptor
;
import
org.springframework.cglib.proxy.MethodProxy
;
import
java.io.Serializable
;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.Method
;
/**
* Spring-cglib实现的动态代理切面
*
* @author looly
*/
public
class
SpringCglibInterceptor
implements
MethodInterceptor
,
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
private
final
Object
target
;
private
final
Aspect
aspect
;
/**
* 构造
*
* @param target 被代理对象
* @param aspect 切面实现
*/
public
SpringCglibInterceptor
(
Object
target
,
Aspect
aspect
)
{
this
.
target
=
target
;
this
.
aspect
=
aspect
;
}
/**
* 获得目标对象
*
* @return 目标对象
*/
public
Object
getTarget
()
{
return
this
.
target
;
}
@Override
public
Object
intercept
(
Object
obj
,
Method
method
,
Object
[]
args
,
MethodProxy
proxy
)
throws
Throwable
{
final
Object
target
=
this
.
target
;
Object
result
=
null
;
// 开始前回调
if
(
aspect
.
before
(
target
,
method
,
args
))
{
try
{
// result = proxy.invokeSuper(obj, args);
result
=
proxy
.
invoke
(
target
,
args
);
}
catch
(
InvocationTargetException
e
)
{
// 异常回调(只捕获业务代码导致的异常,而非反射导致的异常)
if
(
aspect
.
afterException
(
target
,
method
,
args
,
e
.
getTargetException
()))
{
throw
e
;
}
}
}
// 结束执行回调
if
(
aspect
.
after
(
target
,
method
,
args
,
result
))
{
return
result
;
}
return
null
;
}
}
hutool-aop/src/main/java/cn/hutool/aop/interceptor/package-info.java
0 → 100644
View file @
45cda665
/**
* 代理拦截器实现
*
* @author looly
*
*/
package
cn.hutool.aop.interceptor
;
\ No newline at end of file
hutool-aop/src/main/java/cn/hutool/aop/package-info.java
0 → 100644
View file @
45cda665
/**
* JDK动态代理封装,提供非IOC下的切面支持
*
* @author looly
*
*/
package
cn.hutool.aop
;
\ No newline at end of file
hutool-aop/src/main/java/cn/hutool/aop/proxy/CglibProxyFactory.java
0 → 100644
View file @
45cda665
package
cn.hutool.aop.proxy
;
import
cn.hutool.aop.aspects.Aspect
;
import
cn.hutool.aop.interceptor.CglibInterceptor
;
import
cn.hutool.core.util.ClassUtil
;
import
cn.hutool.core.util.ReflectUtil
;
import
net.sf.cglib.proxy.Enhancer
;
import
java.lang.reflect.Constructor
;
/**
* 基于Cglib的切面代理工厂
*
* @author looly
*
*/
public
class
CglibProxyFactory
extends
ProxyFactory
{
private
static
final
long
serialVersionUID
=
1L
;
@Override
public
<
T
>
T
proxy
(
T
target
,
Aspect
aspect
)
{
final
Class
<?>
targetClass
=
target
.
getClass
();
final
Enhancer
enhancer
=
new
Enhancer
();
enhancer
.
setSuperclass
(
target
.
getClass
());
enhancer
.
setCallback
(
new
CglibInterceptor
(
target
,
aspect
));
return
create
(
enhancer
,
targetClass
);
}
/**
* 创建代理对象<br>
* https://gitee.com/dromara/hutool/issues/I74EX7<br>
* 某些对象存在非空参数构造,则需遍历查找需要的构造完成代理对象构建。
*
* @param <T> 代理对象类型
* @param enhancer {@link org.springframework.cglib.proxy.Enhancer}
* @param targetClass 目标类型
* @return 代理对象
*/
@SuppressWarnings
(
"unchecked"
)
private
static
<
T
>
T
create
(
final
Enhancer
enhancer
,
final
Class
<?>
targetClass
)
{
final
Constructor
<?>[]
constructors
=
ReflectUtil
.
getConstructors
(
targetClass
);
Class
<?>[]
parameterTypes
;
Object
[]
values
;
IllegalArgumentException
finalException
=
null
;
for
(
final
Constructor
<?>
constructor
:
constructors
)
{
parameterTypes
=
constructor
.
getParameterTypes
();
values
=
ClassUtil
.
getDefaultValues
(
parameterTypes
);
try
{
return
(
T
)
enhancer
.
create
(
parameterTypes
,
values
);
}
catch
(
final
IllegalArgumentException
e
)
{
//ignore
finalException
=
e
;
}
}
if
(
null
!=
finalException
)
{
throw
finalException
;
}
throw
new
IllegalArgumentException
(
"No constructor provided"
);
}
}
hutool-aop/src/main/java/cn/hutool/aop/proxy/JdkProxyFactory.java
0 → 100644
View file @
45cda665
package
cn.hutool.aop.proxy
;
import
cn.hutool.aop.ProxyUtil
;
import
cn.hutool.aop.aspects.Aspect
;
import
cn.hutool.aop.interceptor.JdkInterceptor
;
/**
* JDK实现的切面代理
*
* @author looly
*/
public
class
JdkProxyFactory
extends
ProxyFactory
{
private
static
final
long
serialVersionUID
=
1L
;
@Override
public
<
T
>
T
proxy
(
T
target
,
Aspect
aspect
)
{
return
ProxyUtil
.
newProxyInstance
(
//
target
.
getClass
().
getClassLoader
(),
//
new
JdkInterceptor
(
target
,
aspect
),
//
target
.
getClass
().
getInterfaces
());
}
}
hutool-aop/src/main/java/cn/hutool/aop/proxy/ProxyFactory.java
0 → 100644
View file @
45cda665
package
cn.hutool.aop.proxy
;
import
cn.hutool.aop.aspects.Aspect
;
import
cn.hutool.core.util.ReflectUtil
;
import
cn.hutool.core.util.ServiceLoaderUtil
;
import
java.io.Serializable
;
/**
* 代理工厂<br>
* 根据用户引入代理库的不同,产生不同的代理对象
*
* @author looly
*/
public
abstract
class
ProxyFactory
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
/**
* 创建代理
*
* @param <T> 代理对象类型
* @param target 被代理对象
* @param aspectClass 切面实现类,自动实例化
* @return 代理对象
* @since 5.3.1
*/
public
<
T
>
T
proxy
(
T
target
,
Class
<?
extends
Aspect
>
aspectClass
)
{
return
proxy
(
target
,
ReflectUtil
.
newInstanceIfPossible
(
aspectClass
));
}
/**
* 创建代理
*
* @param <T> 代理对象类型
* @param target 被代理对象
* @param aspect 切面实现
* @return 代理对象
*/
public
abstract
<
T
>
T
proxy
(
T
target
,
Aspect
aspect
);
/**
* 根据用户引入Cglib与否自动创建代理对象
*
* @param <T> 切面对象类型
* @param target 目标对象
* @param aspectClass 切面对象类
* @return 代理对象
*/
public
static
<
T
>
T
createProxy
(
T
target
,
Class
<?
extends
Aspect
>
aspectClass
)
{
return
createProxy
(
target
,
ReflectUtil
.
newInstance
(
aspectClass
));
}
/**
* 根据用户引入Cglib与否自动创建代理对象
*
* @param <T> 切面对象类型
* @param target 被代理对象
* @param aspect 切面实现
* @return 代理对象
*/
public
static
<
T
>
T
createProxy
(
T
target
,
Aspect
aspect
)
{
return
create
().
proxy
(
target
,
aspect
);
}
/**
* 根据用户引入Cglib与否创建代理工厂
*
* @return 代理工厂
*/
public
static
ProxyFactory
create
()
{
return
ServiceLoaderUtil
.
loadFirstAvailable
(
ProxyFactory
.
class
);
}
}
hutool-aop/src/main/java/cn/hutool/aop/proxy/SpringCglibProxyFactory.java
0 → 100644
View file @
45cda665
package
cn.hutool.aop.proxy
;
import
cn.hutool.aop.aspects.Aspect
;
import
cn.hutool.aop.interceptor.SpringCglibInterceptor
;
import
cn.hutool.core.util.ClassUtil
;
import
cn.hutool.core.util.ReflectUtil
;
import
org.springframework.cglib.proxy.Enhancer
;
import
java.lang.reflect.Constructor
;
/**
* 基于Spring-cglib的切面代理工厂
*
* @author looly
*
*/
public
class
SpringCglibProxyFactory
extends
ProxyFactory
{
private
static
final
long
serialVersionUID
=
1L
;
@Override
public
<
T
>
T
proxy
(
T
target
,
Aspect
aspect
)
{
final
Class
<?>
targetClass
=
target
.
getClass
();
final
Enhancer
enhancer
=
new
Enhancer
();
enhancer
.
setSuperclass
(
targetClass
);
enhancer
.
setCallback
(
new
SpringCglibInterceptor
(
target
,
aspect
));
return
create
(
enhancer
,
targetClass
);
}
/**
* 创建代理对象<br>
* https://gitee.com/dromara/hutool/issues/I74EX7<br>
* 某些对象存在非空参数构造,则需遍历查找需要的构造完成代理对象构建。
*
* @param <T> 代理对象类型
* @param enhancer {@link Enhancer}
* @param targetClass 目标类型
* @return 代理对象
*/
@SuppressWarnings
(
"unchecked"
)
private
static
<
T
>
T
create
(
final
Enhancer
enhancer
,
final
Class
<?>
targetClass
)
{
final
Constructor
<?>[]
constructors
=
ReflectUtil
.
getConstructors
(
targetClass
);
Class
<?>[]
parameterTypes
;
Object
[]
values
;
IllegalArgumentException
finalException
=
null
;
for
(
final
Constructor
<?>
constructor
:
constructors
)
{
parameterTypes
=
constructor
.
getParameterTypes
();
values
=
ClassUtil
.
getDefaultValues
(
parameterTypes
);
try
{
return
(
T
)
enhancer
.
create
(
parameterTypes
,
values
);
}
catch
(
final
IllegalArgumentException
e
)
{
//ignore
finalException
=
e
;
}
}
if
(
null
!=
finalException
)
{
throw
finalException
;
}
throw
new
IllegalArgumentException
(
"No constructor provided"
);
}
}
hutool-aop/src/main/java/cn/hutool/aop/proxy/package-info.java
0 → 100644
View file @
45cda665
/**
* 代理实现
*
* @author looly
*
*/
package
cn.hutool.aop.proxy
;
\ No newline at end of file
hutool-aop/src/main/resources/META-INF/services/cn.hutool.aop.proxy.ProxyFactory
0 → 100644
View file @
45cda665
cn.hutool.aop.proxy.CglibProxyFactory
cn.hutool.aop.proxy.SpringCglibProxyFactory
cn.hutool.aop.proxy.JdkProxyFactory
\ No newline at end of file
hutool-aop/src/test/java/cn/hutool/aop/test/AopTest.java
0 → 100644
View file @
45cda665
package
cn.hutool.aop.test
;
import
cn.hutool.aop.ProxyUtil
;
import
cn.hutool.aop.aspects.TimeIntervalAspect
;
import
cn.hutool.core.lang.Console
;
import
lombok.Data
;
import
org.junit.Assert
;
import
org.junit.Test
;
/**
* AOP模块单元测试
*
* @author Looly
*/
public
class
AopTest
{
@Test
public
void
aopTest
()
{
Animal
cat
=
ProxyUtil
.
proxy
(
new
Cat
(),
TimeIntervalAspect
.
class
);
String
result
=
cat
.
eat
();
Assert
.
assertEquals
(
"猫吃鱼"
,
result
);
cat
.
seize
();
}
@Test
public
void
aopByAutoCglibTest
()
{
Dog
dog
=
ProxyUtil
.
proxy
(
new
Dog
(),
TimeIntervalAspect
.
class
);
String
result
=
dog
.
eat
();
Assert
.
assertEquals
(
"狗吃肉"
,
result
);
dog
.
seize
();
}
interface
Animal
{
String
eat
();
void
seize
();
}
/**
* 有接口
*
* @author looly
*/
static
class
Cat
implements
Animal
{
@Override
public
String
eat
()
{
return
"猫吃鱼"
;
}
@Override
public
void
seize
()
{
Console
.
log
(
"抓了条鱼"
);
}
}
/**
* 无接口
*
* @author looly
*/
static
class
Dog
{
public
String
eat
()
{
return
"狗吃肉"
;
}
public
void
seize
()
{
Console
.
log
(
"抓了只鸡"
);
}
}
@Test
public
void
testCGLIBProxy
()
{
TagObj
target
=
new
TagObj
();
//目标类设置标记
target
.
setTag
(
"tag"
);
TagObj
proxy
=
ProxyUtil
.
proxy
(
target
,
TimeIntervalAspect
.
class
);
//代理类获取标记tag (断言错误)
Assert
.
assertEquals
(
"tag"
,
proxy
.
getTag
());
}
@Data
public
static
class
TagObj
{
private
String
tag
;
}
}
hutool-aop/src/test/java/cn/hutool/aop/test/IssueI74EX7Test.java
0 → 100644
View file @
45cda665
/*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package
cn.hutool.aop.test
;
import
cn.hutool.aop.aspects.SimpleAspect
;
import
cn.hutool.aop.proxy.CglibProxyFactory
;
import
cn.hutool.aop.proxy.JdkProxyFactory
;
import
cn.hutool.aop.proxy.ProxyFactory
;
import
cn.hutool.aop.proxy.SpringCglibProxyFactory
;
import
cn.hutool.core.lang.Console
;
import
lombok.Setter
;
import
org.junit.Test
;
public
class
IssueI74EX7Test
{
@Test
public
void
proxyTest
()
{
final
SmsBlend
smsBlend
=
new
SmsBlendImpl
(
1
);
final
ProxyFactory
engine
=
new
JdkProxyFactory
();
engine
.
proxy
(
smsBlend
,
new
SimpleAspect
());
}
/**
* https://gitee.com/dromara/hutool/issues/I74EX7<br>
* Enhancer.create()默认调用无参构造,有参构造或者多个构造没有很好的兼容。
*
*/
@Test
public
void
cglibProxyTest
()
{
final
SmsBlend
smsBlend
=
new
SmsBlendImpl
(
1
);
final
ProxyFactory
engine
=
new
CglibProxyFactory
();
engine
.
proxy
(
smsBlend
,
new
SimpleAspect
());
}
/**
* https://gitee.com/dromara/hutool/issues/I74EX7<br>
* Enhancer.create()默认调用无参构造,有参构造或者多个构造没有很好的兼容。
*
*/
@Test
public
void
springCglibProxyTest
()
{
final
SmsBlend
smsBlend
=
new
SmsBlendImpl
(
1
);
final
ProxyFactory
engine
=
new
SpringCglibProxyFactory
();
engine
.
proxy
(
smsBlend
,
new
SimpleAspect
());
}
@Test
public
void
springCglibProxyWithoutConstructorTest
()
{
final
SmsBlend
smsBlend
=
new
SmsBlendImplWithoutConstructor
();
final
ProxyFactory
engine
=
new
SpringCglibProxyFactory
();
engine
.
proxy
(
smsBlend
,
new
SimpleAspect
());
}
public
interface
SmsBlend
{
void
send
();
}
public
static
class
SmsBlendImpl
implements
SmsBlend
{
private
final
int
status
;
public
SmsBlendImpl
(
final
int
status
)
{
this
.
status
=
status
;
}
@Override
public
void
send
()
{
Console
.
log
(
"sms send."
+
status
);
}
}
@Setter
public
static
class
SmsBlendImplWithoutConstructor
implements
SmsBlend
{
private
int
status
;
@Override
public
void
send
()
{
Console
.
log
(
"sms send."
+
status
);
}
}
}
hutool-bloomFilter/pom.xml
0 → 100644
View file @
45cda665
<?xml version='1.0' encoding='utf-8'?>
<project
xmlns=
"http://maven.apache.org/POM/4.0.0"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
>
<modelVersion>
4.0.0
</modelVersion>
<packaging>
jar
</packaging>
<parent>
<groupId>
cn.hutool
</groupId>
<artifactId>
hutool-parent
</artifactId>
<version>
5.8.19
</version>
</parent>
<artifactId>
hutool-bloomFilter
</artifactId>
<name>
${project.artifactId}
</name>
<description>
Hutool 布隆过滤器
</description>
<properties>
<Automatic-Module-Name>
cn.hutool.bloomfilter
</Automatic-Module-Name>
</properties>
<dependencies>
<dependency>
<groupId>
cn.hutool
</groupId>
<artifactId>
hutool-core
</artifactId>
<version>
${project.parent.version}
</version>
</dependency>
</dependencies>
</project>
hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/BitMapBloomFilter.java
0 → 100644
View file @
45cda665
package
cn.hutool.bloomfilter
;
import
cn.hutool.bloomfilter.filter.DefaultFilter
;
import
cn.hutool.bloomfilter.filter.ELFFilter
;
import
cn.hutool.bloomfilter.filter.JSFilter
;
import
cn.hutool.bloomfilter.filter.PJWFilter
;
import
cn.hutool.bloomfilter.filter.SDBMFilter
;
import
cn.hutool.core.util.NumberUtil
;
/**
* BloomFilter 实现 <br>
* 1.构建hash算法 <br>
* 2.散列hash映射到数组的bit位置 <br>
* 3.验证<br>
* 此实现方式可以指定Hash算法
*
* @author Ansj
*/
public
class
BitMapBloomFilter
implements
BloomFilter
{
private
static
final
long
serialVersionUID
=
1L
;
private
BloomFilter
[]
filters
;
/**
* 构造,使用默认的5个过滤器
*
* @param m M值决定BitMap的大小
*/
public
BitMapBloomFilter
(
int
m
)
{
long
mNum
=
NumberUtil
.
div
(
String
.
valueOf
(
m
),
String
.
valueOf
(
5
)).
longValue
();
long
size
=
mNum
*
1024
*
1024
*
8
;
filters
=
new
BloomFilter
[]{
new
DefaultFilter
(
size
),
new
ELFFilter
(
size
),
new
JSFilter
(
size
),
new
PJWFilter
(
size
),
new
SDBMFilter
(
size
)
};
}
/**
* 使用自定的多个过滤器建立BloomFilter
*
* @param m M值决定BitMap的大小
* @param filters Bloom过滤器列表
*/
public
BitMapBloomFilter
(
int
m
,
BloomFilter
...
filters
)
{
this
(
m
);
this
.
filters
=
filters
;
}
/**
* 增加字符串到Filter映射中
*
* @param str 字符串
*/
@Override
public
boolean
add
(
String
str
)
{
boolean
flag
=
false
;
for
(
BloomFilter
filter
:
filters
)
{
flag
|=
filter
.
add
(
str
);
}
return
flag
;
}
/**
* 是否可能包含此字符串,此处存在误判
*
* @param str 字符串
* @return 是否存在
*/
@Override
public
boolean
contains
(
String
str
)
{
for
(
BloomFilter
filter
:
filters
)
{
if
(
filter
.
contains
(
str
)
==
false
)
{
return
false
;
}
}
return
true
;
}
}
hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/BitSetBloomFilter.java
0 → 100644
View file @
45cda665
package
cn.hutool.bloomfilter
;
import
cn.hutool.core.io.FileUtil
;
import
cn.hutool.core.io.IoUtil
;
import
cn.hutool.core.util.CharsetUtil
;
import
cn.hutool.core.util.HashUtil
;
import
java.io.BufferedReader
;
import
java.io.IOException
;
import
java.nio.charset.Charset
;
import
java.util.BitSet
;
/**
* BloomFilter实现方式2,此方式使用BitSet存储。<br>
* Hash算法的使用使用固定顺序,只需指定个数即可
*
* @author loolly
*/
public
class
BitSetBloomFilter
implements
BloomFilter
{
private
static
final
long
serialVersionUID
=
1L
;
private
final
BitSet
bitSet
;
private
final
int
bitSetSize
;
private
final
int
addedElements
;
private
final
int
hashFunctionNumber
;
/**
* 构造一个布隆过滤器,过滤器的容量为c * n 个bit.
*
* @param c 当前过滤器预先开辟的最大包含记录,通常要比预计存入的记录多一倍.
* @param n 当前过滤器预计所要包含的记录.
* @param k 哈希函数的个数,等同每条记录要占用的bit数.
*/
public
BitSetBloomFilter
(
int
c
,
int
n
,
int
k
)
{
this
.
hashFunctionNumber
=
k
;
this
.
bitSetSize
=
(
int
)
Math
.
ceil
(
c
*
k
);
this
.
addedElements
=
n
;
this
.
bitSet
=
new
BitSet
(
this
.
bitSetSize
);
}
/**
* 通过文件初始化过滤器.
*
* @param path 文件路径
* @param charsetName 字符集
* @throws IOException IO异常
* @deprecated 请使用 {@link #init(String, Charset)}
*/
@Deprecated
public
void
init
(
String
path
,
String
charsetName
)
throws
IOException
{
init
(
path
,
CharsetUtil
.
charset
(
charsetName
));
}
/**
* 通过文件初始化过滤器.
*
* @param path 文件路径
* @param charset 字符集
* @throws IOException IO异常
* @since 5.8.0
*/
public
void
init
(
String
path
,
Charset
charset
)
throws
IOException
{
BufferedReader
reader
=
FileUtil
.
getReader
(
path
,
charset
);
try
{
String
line
;
while
(
true
)
{
line
=
reader
.
readLine
();
if
(
line
==
null
)
{
break
;
}
this
.
add
(
line
);
}
}
finally
{
IoUtil
.
close
(
reader
);
}
}
@Override
public
boolean
add
(
String
str
)
{
if
(
contains
(
str
))
{
return
false
;
}
int
[]
positions
=
createHashes
(
str
,
hashFunctionNumber
);
for
(
int
value
:
positions
)
{
int
position
=
Math
.
abs
(
value
%
bitSetSize
);
bitSet
.
set
(
position
,
true
);
}
return
true
;
}
/**
* 判定是否包含指定字符串
*
* @param str 字符串
* @return 是否包含,存在误差
*/
@Override
public
boolean
contains
(
String
str
)
{
int
[]
positions
=
createHashes
(
str
,
hashFunctionNumber
);
for
(
int
i
:
positions
)
{
int
position
=
Math
.
abs
(
i
%
bitSetSize
);
if
(!
bitSet
.
get
(
position
))
{
return
false
;
}
}
return
true
;
}
/**
* @return 得到当前过滤器的错误率.
*/
public
double
getFalsePositiveProbability
()
{
// (1 - e^(-k * n / m)) ^ k
return
Math
.
pow
((
1
-
Math
.
exp
(-
hashFunctionNumber
*
(
double
)
addedElements
/
bitSetSize
)),
hashFunctionNumber
);
}
/**
* 将字符串的字节表示进行多哈希编码.
*
* @param str 待添加进过滤器的字符串字节表示.
* @param hashNumber 要经过的哈希个数.
* @return 各个哈希的结果数组.
*/
public
static
int
[]
createHashes
(
String
str
,
int
hashNumber
)
{
int
[]
result
=
new
int
[
hashNumber
];
for
(
int
i
=
0
;
i
<
hashNumber
;
i
++)
{
result
[
i
]
=
hash
(
str
,
i
);
}
return
result
;
}
/**
* 计算Hash值
*
* @param str 被计算Hash的字符串
* @param k Hash算法序号
* @return Hash值
*/
public
static
int
hash
(
String
str
,
int
k
)
{
switch
(
k
)
{
case
0
:
return
HashUtil
.
rsHash
(
str
);
case
1
:
return
HashUtil
.
jsHash
(
str
);
case
2
:
return
HashUtil
.
elfHash
(
str
);
case
3
:
return
HashUtil
.
bkdrHash
(
str
);
case
4
:
return
HashUtil
.
apHash
(
str
);
case
5
:
return
HashUtil
.
djbHash
(
str
);
case
6
:
return
HashUtil
.
sdbmHash
(
str
);
case
7
:
return
HashUtil
.
pjwHash
(
str
);
default
:
return
0
;
}
}
}
hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/BloomFilter.java
0 → 100644
View file @
45cda665
package
cn.hutool.bloomfilter
;
import
java.io.Serializable
;
/**
* Bloom filter 是由 Howard Bloom 在 1970 年提出的二进制向量数据结构,它具有很好的空间和时间效率,被用来检测一个元素是不是集合中的一个成员。<br>
* 如果检测结果为是,该元素不一定在集合中;但如果检测结果为否,该元素一定不在集合中。<br>
* 因此Bloom filter具有100%的召回率。这样每个检测请求返回有“在集合内(可能错误)”和“不在集合内(绝对不在集合内)”两种情况。<br>
* @author Looly
*
*/
public
interface
BloomFilter
extends
Serializable
{
/**
*
* @param str 字符串
* @return 判断一个字符串是否bitMap中存在
*/
boolean
contains
(
String
str
);
/**
* 在boolean的bitMap中增加一个字符串<br>
* 如果存在就返回{@code false} .如果不存在.先增加这个字符串.再返回{@code true}
*
* @param str 字符串
* @return 是否加入成功,如果存在就返回{@code false} .如果不存在返回{@code true}
*/
boolean
add
(
String
str
);
}
hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/BloomFilterUtil.java
0 → 100644
View file @
45cda665
package
cn.hutool.bloomfilter
;
/**
* 布隆过滤器工具
*
* @author looly
* @since 4.1.5
*/
public
class
BloomFilterUtil
{
/**
* 创建一个BitSet实现的布隆过滤器,过滤器的容量为c * n 个bit.
*
* @param c 当前过滤器预先开辟的最大包含记录,通常要比预计存入的记录多一倍.
* @param n 当前过滤器预计所要包含的记录.
* @param k 哈希函数的个数,等同每条记录要占用的bit数.
* @return BitSetBloomFilter
*/
public
static
BitSetBloomFilter
createBitSet
(
int
c
,
int
n
,
int
k
)
{
return
new
BitSetBloomFilter
(
c
,
n
,
k
);
}
/**
* 创建BitMap实现的布隆过滤器
*
* @param m BitMap的大小
* @return BitMapBloomFilter
*/
public
static
BitMapBloomFilter
createBitMap
(
int
m
)
{
return
new
BitMapBloomFilter
(
m
);
}
}
hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/bitMap/BitMap.java
0 → 100644
View file @
45cda665
package
cn.hutool.bloomfilter.bitMap
;
/**
* BitMap接口,用于将某个int或long值映射到一个数组中,从而判定某个值是否存在
*
* @author looly
*
*/
public
interface
BitMap
{
int
MACHINE32
=
32
;
int
MACHINE64
=
64
;
/**
* 加入值
*
* @param i 值
*/
void
add
(
long
i
);
/**
* 检查是否包含值
*
* @param i 值
* @return 是否包含
*/
boolean
contains
(
long
i
);
/**
* 移除值
*
* @param i 值
*/
void
remove
(
long
i
);
}
\ No newline at end of file
hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/bitMap/IntMap.java
0 → 100644
View file @
45cda665
package
cn.hutool.bloomfilter.bitMap
;
import
java.io.Serializable
;
/**
* 过滤器BitMap在32位机器上.这个类能发生更好的效果.一般情况下建议使用此类
*
* @author loolly
*
*/
public
class
IntMap
implements
BitMap
,
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
private
final
int
[]
ints
;
/**
* 构造
*/
public
IntMap
()
{
ints
=
new
int
[
93750000
];
}
/**
* 构造
*
* @param size 容量
*/
public
IntMap
(
int
size
)
{
ints
=
new
int
[
size
];
}
@Override
public
void
add
(
long
i
)
{
int
r
=
(
int
)
(
i
/
BitMap
.
MACHINE32
);
int
c
=
(
int
)
(
i
&
(
BitMap
.
MACHINE32
-
1
));
ints
[
r
]
=
ints
[
r
]
|
(
1
<<
c
);
}
@Override
public
boolean
contains
(
long
i
)
{
int
r
=
(
int
)
(
i
/
BitMap
.
MACHINE32
);
int
c
=
(
int
)
(
i
&
(
BitMap
.
MACHINE32
-
1
));
return
((
ints
[
r
]
>>>
c
)
&
1
)
==
1
;
}
@Override
public
void
remove
(
long
i
)
{
int
r
=
(
int
)
(
i
/
BitMap
.
MACHINE32
);
int
c
=
(
int
)
(
i
&
(
BitMap
.
MACHINE32
-
1
));
ints
[
r
]
&=
~(
1
<<
c
);
}
}
hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/bitMap/LongMap.java
0 → 100644
View file @
45cda665
package
cn.hutool.bloomfilter.bitMap
;
import
java.io.Serializable
;
/**
* 过滤器BitMap在64位机器上.这个类能发生更好的效果.一般机器不建议使用
*
* @author loolly
*
*/
public
class
LongMap
implements
BitMap
,
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
private
final
long
[]
longs
;
/**
* 构造
*/
public
LongMap
()
{
longs
=
new
long
[
93750000
];
}
/**
* 构造
*
* @param size 容量
*/
public
LongMap
(
int
size
)
{
longs
=
new
long
[
size
];
}
@Override
public
void
add
(
long
i
)
{
int
r
=
(
int
)
(
i
/
BitMap
.
MACHINE64
);
long
c
=
i
&
(
BitMap
.
MACHINE64
-
1
);
longs
[
r
]
=
longs
[
r
]
|
(
1L
<<
c
);
}
@Override
public
boolean
contains
(
long
i
)
{
int
r
=
(
int
)
(
i
/
BitMap
.
MACHINE64
);
long
c
=
i
&
(
BitMap
.
MACHINE64
-
1
);
return
((
longs
[
r
]
>>>
c
)
&
1
)
==
1
;
}
@Override
public
void
remove
(
long
i
)
{
int
r
=
(
int
)
(
i
/
BitMap
.
MACHINE64
);
long
c
=
i
&
(
BitMap
.
MACHINE64
-
1
);
longs
[
r
]
&=
~(
1L
<<
c
);
}
}
hutool-bloomFilter/src/main/java/cn/hutool/bloomfilter/bitMap/package-info.java
0 → 100644
View file @
45cda665
/**
* BitMap实现
*
* @author looly
*
*/
package
cn.hutool.bloomfilter.bitMap
;
\ No newline at end of file
Prev
1
2
3
4
5
6
7
…
19
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment