Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
d48f308c
提交
d48f308c
authored
6 年前
作者:
Evgenij Ryazanov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Do not load the whole LOBs into memory for comparison operation
上级
1e462004
隐藏空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
163 行增加
和
12 行删除
+163
-12
Bits.class
h2/src/java9/precompiled/org/h2/util/Bits.class
+0
-0
Bits.java
h2/src/java9/src/org/h2/util/Bits.java
+16
-0
Bits.java
h2/src/main/org/h2/util/Bits.java
+27
-0
ValueLob.java
h2/src/main/org/h2/value/ValueLob.java
+84
-5
ValueLobDb.java
h2/src/main/org/h2/value/ValueLobDb.java
+2
-7
TestValue.java
h2/src/test/org/h2/test/unit/TestValue.java
+34
-0
没有找到文件。
h2/src/java9/precompiled/org/h2/util/Bits.class
浏览文件 @
d48f308c
No preview for this file type
This diff is collapsed.
Click to expand it.
h2/src/java9/src/org/h2/util/Bits.java
浏览文件 @
d48f308c
...
...
@@ -29,6 +29,22 @@ public final class Bits {
*/
private
static
final
VarHandle
LONG_VH
=
MethodHandles
.
byteArrayViewVarHandle
(
long
[].
class
,
ByteOrder
.
BIG_ENDIAN
);
/**
* Compare the contents of two char arrays. If the content or length of the
* first array is smaller than the second array, -1 is returned. If the content
* or length of the second array is smaller than the first array, 1 is returned.
* If the contents and lengths are the same, 0 is returned.
*
* @param data1
* the first char array (must not be null)
* @param data2
* the second char array (must not be null)
* @return the result of the comparison (-1, 1 or 0)
*/
public
static
int
compareNotNull
(
char
[]
data1
,
char
[]
data2
)
{
return
Integer
.
signum
(
Arrays
.
compare
(
data1
,
data2
));
}
/**
* Compare the contents of two byte arrays. If the content or length of the
* first array is smaller than the second array, -1 is returned. If the content
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/util/Bits.java
浏览文件 @
d48f308c
...
...
@@ -20,6 +20,33 @@ public final class Bits {
* h2/src/java9/precompiled/org/h2/util/Bits.class.
*/
/**
* Compare the contents of two char arrays. If the content or length of the
* first array is smaller than the second array, -1 is returned. If the content
* or length of the second array is smaller than the first array, 1 is returned.
* If the contents and lengths are the same, 0 is returned.
*
* @param data1
* the first char array (must not be null)
* @param data2
* the second char array (must not be null)
* @return the result of the comparison (-1, 1 or 0)
*/
public
static
int
compareNotNull
(
char
[]
data1
,
char
[]
data2
)
{
if
(
data1
==
data2
)
{
return
0
;
}
int
len
=
Math
.
min
(
data1
.
length
,
data2
.
length
);
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
char
b
=
data1
[
i
];
char
b2
=
data2
[
i
];
if
(
b
!=
b2
)
{
return
b
>
b2
?
1
:
-
1
;
}
}
return
Integer
.
signum
(
data1
.
length
-
data2
.
length
);
}
/**
* Compare the contents of two byte arrays. If the content or length of the
* first array is smaller than the second array, -1 is returned. If the content
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/value/ValueLob.java
浏览文件 @
d48f308c
...
...
@@ -35,6 +35,8 @@ import org.h2.util.Utils;
*/
public
class
ValueLob
extends
Value
{
private
static
final
int
BLOCK_COMPARISON_SIZE
=
512
;
private
static
void
rangeCheckUnknown
(
long
zeroBasedOffset
,
long
length
)
{
if
(
zeroBasedOffset
<
0
)
{
throw
DbException
.
getInvalidValueException
(
"offset"
,
zeroBasedOffset
+
1
);
...
...
@@ -66,6 +68,87 @@ public class ValueLob extends Value {
}
}
/**
* Compares LOBs of the same type.
*
* @param valueType type
* @param v1 first LOB value
* @param v2 second LOB value
* @return result of comparison
*/
static
int
compare
(
int
valueType
,
Value
v1
,
Value
v2
)
{
long
prec1
=
v1
.
getPrecision
(),
prec2
=
v2
.
getPrecision
();
if
(
Math
.
max
(
prec1
,
prec2
)
<=
BLOCK_COMPARISON_SIZE
)
{
if
(
valueType
==
Value
.
BLOB
)
{
return
Bits
.
compareNotNullSigned
(
v1
.
getBytesNoCopy
(),
v2
.
getBytesNoCopy
());
}
else
{
return
Integer
.
signum
(
v1
.
getString
().
compareTo
(
v2
.
getString
()));
}
}
long
minPrec
=
Math
.
min
(
prec1
,
prec2
);
if
(
valueType
==
Value
.
BLOB
)
{
try
(
InputStream
is1
=
v1
.
getInputStream
();
InputStream
is2
=
v2
.
getInputStream
())
{
byte
[]
buf1
=
new
byte
[
BLOCK_COMPARISON_SIZE
];
byte
[]
buf2
=
new
byte
[
BLOCK_COMPARISON_SIZE
];
for
(;
minPrec
>=
BLOCK_COMPARISON_SIZE
;
minPrec
-=
BLOCK_COMPARISON_SIZE
)
{
if
(
IOUtils
.
readFully
(
is1
,
buf1
,
BLOCK_COMPARISON_SIZE
)
!=
BLOCK_COMPARISON_SIZE
||
IOUtils
.
readFully
(
is2
,
buf2
,
BLOCK_COMPARISON_SIZE
)
!=
BLOCK_COMPARISON_SIZE
)
{
throw
DbException
.
getUnsupportedException
(
"Invalid LOB"
);
}
int
cmp
=
Bits
.
compareNotNullSigned
(
buf1
,
buf2
);
if
(
cmp
!=
0
)
{
return
cmp
;
}
}
for
(;;)
{
int
c1
=
is1
.
read
(),
c2
=
is2
.
read
();
if
(
c1
<
0
)
{
return
c2
<
0
?
0
:
-
1
;
}
if
(
c2
<
0
)
{
return
1
;
}
if
(
c1
!=
c2
)
{
return
Integer
.
compare
(
c1
,
c2
);
}
}
}
catch
(
IOException
ex
)
{
throw
DbException
.
convert
(
ex
);
}
}
else
{
try
(
Reader
reader1
=
v1
.
getReader
();
Reader
reader2
=
v2
.
getReader
())
{
char
[]
buf1
=
new
char
[
BLOCK_COMPARISON_SIZE
];
char
[]
buf2
=
new
char
[
BLOCK_COMPARISON_SIZE
];
for
(;
minPrec
>=
BLOCK_COMPARISON_SIZE
;
minPrec
-=
BLOCK_COMPARISON_SIZE
)
{
if
(
IOUtils
.
readFully
(
reader1
,
buf1
,
BLOCK_COMPARISON_SIZE
)
!=
BLOCK_COMPARISON_SIZE
||
IOUtils
.
readFully
(
reader2
,
buf2
,
BLOCK_COMPARISON_SIZE
)
!=
BLOCK_COMPARISON_SIZE
)
{
throw
DbException
.
getUnsupportedException
(
"Invalid LOB"
);
}
int
cmp
=
Bits
.
compareNotNull
(
buf1
,
buf2
);
if
(
cmp
!=
0
)
{
return
cmp
;
}
}
for
(;;)
{
int
c1
=
reader1
.
read
(),
c2
=
reader2
.
read
();
if
(
c1
<
0
)
{
return
c2
<
0
?
0
:
-
1
;
}
if
(
c2
<
0
)
{
return
1
;
}
if
(
c1
!=
c2
)
{
return
Integer
.
compare
(
c1
,
c2
);
}
}
}
catch
(
IOException
ex
)
{
throw
DbException
.
convert
(
ex
);
}
}
}
/**
* Create a reader that is s subset of the given reader.
*
...
...
@@ -430,11 +513,7 @@ public class ValueLob extends Value {
@Override
protected
int
compareSecure
(
Value
v
,
CompareMode
mode
)
{
if
(
valueType
==
Value
.
CLOB
)
{
return
Integer
.
signum
(
getString
().
compareTo
(
v
.
getString
()));
}
byte
[]
v2
=
v
.
getBytesNoCopy
();
return
Bits
.
compareNotNullSigned
(
getBytesNoCopy
(),
v2
);
return
compare
(
valueType
,
this
,
v
);
}
@Override
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/value/ValueLobDb.java
浏览文件 @
d48f308c
...
...
@@ -26,7 +26,6 @@ import org.h2.store.LobStorageFrontend;
import
org.h2.store.LobStorageInterface
;
import
org.h2.store.RangeReader
;
import
org.h2.store.fs.FileUtils
;
import
org.h2.util.Bits
;
import
org.h2.util.IOUtils
;
import
org.h2.util.MathUtils
;
import
org.h2.util.StringUtils
;
...
...
@@ -386,11 +385,7 @@ public class ValueLobDb extends Value {
return
0
;
}
}
if
(
valueType
==
Value
.
CLOB
)
{
return
Integer
.
signum
(
getString
().
compareTo
(
v
.
getString
()));
}
byte
[]
v2
=
v
.
getBytesNoCopy
();
return
Bits
.
compareNotNullSigned
(
getBytesNoCopy
(),
v2
);
return
ValueLob
.
compare
(
valueType
,
this
,
v
);
}
@Override
...
...
@@ -720,7 +715,7 @@ public class ValueLobDb extends Value {
* @param small the byte array
* @return the LOB
*/
public
static
Value
createSmallLob
(
int
type
,
byte
[]
small
)
{
public
static
Value
LobDb
createSmallLob
(
int
type
,
byte
[]
small
)
{
int
precision
;
if
(
type
==
Value
.
CLOB
)
{
precision
=
new
String
(
small
,
StandardCharsets
.
UTF_8
).
length
();
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/unit/TestValue.java
浏览文件 @
d48f308c
...
...
@@ -70,6 +70,7 @@ public class TestValue extends TestDb {
testModulusDouble
();
testModulusDecimal
();
testModulusOperator
();
testLobComparison
();
}
private
void
testResultSetOperations
()
throws
SQLException
{
...
...
@@ -415,4 +416,37 @@ public class TestValue extends TestDb {
}
}
private
void
testLobComparison
()
{
assertEquals
(
0
,
testLobComparisonImpl
(
Value
.
BLOB
,
0
,
0
,
0
,
0
));
assertEquals
(
0
,
testLobComparisonImpl
(
Value
.
CLOB
,
0
,
0
,
0
,
0
));
assertEquals
(-
1
,
testLobComparisonImpl
(
Value
.
BLOB
,
1
,
1
,
200
,
210
));
assertEquals
(-
1
,
testLobComparisonImpl
(
Value
.
CLOB
,
1
,
1
,
'a'
,
'b'
));
assertEquals
(
1
,
testLobComparisonImpl
(
Value
.
BLOB
,
512
,
512
,
210
,
200
));
assertEquals
(
1
,
testLobComparisonImpl
(
Value
.
CLOB
,
512
,
512
,
'B'
,
'A'
));
assertEquals
(
1
,
testLobComparisonImpl
(
Value
.
BLOB
,
1_024
,
1_024
,
210
,
200
));
assertEquals
(
1
,
testLobComparisonImpl
(
Value
.
CLOB
,
1_024
,
1_024
,
'B'
,
'A'
));
assertEquals
(-
1
,
testLobComparisonImpl
(
Value
.
BLOB
,
10_000
,
10_000
,
200
,
210
));
assertEquals
(-
1
,
testLobComparisonImpl
(
Value
.
CLOB
,
10_000
,
10_000
,
'a'
,
'b'
));
assertEquals
(
0
,
testLobComparisonImpl
(
Value
.
BLOB
,
10_000
,
10_000
,
0
,
0
));
assertEquals
(
0
,
testLobComparisonImpl
(
Value
.
CLOB
,
10_000
,
10_000
,
0
,
0
));
assertEquals
(-
1
,
testLobComparisonImpl
(
Value
.
BLOB
,
1_000
,
10_000
,
0
,
0
));
assertEquals
(-
1
,
testLobComparisonImpl
(
Value
.
CLOB
,
1_000
,
10_000
,
0
,
0
));
assertEquals
(
1
,
testLobComparisonImpl
(
Value
.
BLOB
,
10_000
,
1_000
,
0
,
0
));
assertEquals
(
1
,
testLobComparisonImpl
(
Value
.
CLOB
,
10_000
,
1_000
,
0
,
0
));
}
private
static
int
testLobComparisonImpl
(
int
type
,
int
size1
,
int
size2
,
int
suffix1
,
int
suffix2
)
{
byte
[]
bytes1
=
new
byte
[
size1
];
byte
[]
bytes2
=
new
byte
[
size2
];
if
(
size1
>
0
)
{
bytes1
[
size1
-
1
]
=
(
byte
)
suffix1
;
}
if
(
size2
>
0
)
{
bytes2
[
size2
-
1
]
=
(
byte
)
suffix2
;
}
ValueLobDb
lob1
=
ValueLobDb
.
createSmallLob
(
type
,
bytes1
);
ValueLobDb
lob2
=
ValueLobDb
.
createSmallLob
(
type
,
bytes2
);
return
lob1
.
compareTypeSafe
(
lob2
,
null
);
}
}
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论