Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
22e6097b
提交
22e6097b
authored
14 年前
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Storing lobs in the database has been changed. It is now faster.
上级
91516b70
显示空白字符变更
内嵌
并排
正在显示
1 个修改的文件
包含
63 行增加
和
47 行删除
+63
-47
LobStorage.java
h2/src/main/org/h2/store/LobStorage.java
+63
-47
没有找到文件。
h2/src/main/org/h2/store/LobStorage.java
浏览文件 @
22e6097b
...
@@ -50,9 +50,12 @@ public class LobStorage {
...
@@ -50,9 +50,12 @@ public class LobStorage {
private
static
final
String
LOB_DATA
=
"INFORMATION_SCHEMA.LOB_DATA"
;
private
static
final
String
LOB_DATA
=
"INFORMATION_SCHEMA.LOB_DATA"
;
private
static
final
int
BLOCK_LENGTH
=
20000
;
private
static
final
int
BLOCK_LENGTH
=
20000
;
private
static
final
boolean
HASH
=
true
;
// each entry needs 16 bytes (2 longs)
/**
private
static
final
int
HASH_CACHE_SIZE
=
8
*
1024
;
* The size of cache for lob block hashes. Each entry needs 2 longs (16
* bytes), therefore, the size 4096 means 64 KB.
*/
private
static
final
int
HASH_CACHE_SIZE
=
4
*
1024
;
private
Connection
conn
;
private
Connection
conn
;
private
HashMap
<
String
,
PreparedStatement
>
prepared
=
New
.
hashMap
();
private
HashMap
<
String
,
PreparedStatement
>
prepared
=
New
.
hashMap
();
private
long
nextBlock
;
private
long
nextBlock
;
...
@@ -83,9 +86,9 @@ public class LobStorage {
...
@@ -83,9 +86,9 @@ public class LobStorage {
// stat.execute("SET UNDO_LOG 0");
// stat.execute("SET UNDO_LOG 0");
// stat.execute("SET REDO_LOG_BINARY 0");
// stat.execute("SET REDO_LOG_BINARY 0");
stat
.
execute
(
"CREATE TABLE IF NOT EXISTS "
+
LOBS
+
"(ID BIGINT PRIMARY KEY, BYTE_COUNT BIGINT, TABLE INT) HIDDEN"
);
stat
.
execute
(
"CREATE TABLE IF NOT EXISTS "
+
LOBS
+
"(ID BIGINT PRIMARY KEY, BYTE_COUNT BIGINT, TABLE INT) HIDDEN"
);
stat
.
execute
(
"CREATE TABLE IF NOT EXISTS "
+
LOB_MAP
+
"(LOB BIGINT, SEQ INT, BLOCK BIGINT, PRIMARY KEY(LOB, SEQ)) HIDDEN"
);
stat
.
execute
(
"CREATE TABLE IF NOT EXISTS "
+
LOB_MAP
+
"(LOB BIGINT, SEQ INT,
HASH INT,
BLOCK BIGINT, PRIMARY KEY(LOB, SEQ)) HIDDEN"
);
stat
.
execute
(
"CREATE INDEX IF NOT EXISTS INFORMATION_SCHEMA.INDEX_LOB_MAP_DATA_LOB ON "
+
LOB_MAP
+
"(BLOCK, LOB)"
);
stat
.
execute
(
"CREATE INDEX IF NOT EXISTS INFORMATION_SCHEMA.INDEX_LOB_MAP_DATA_LOB ON "
+
LOB_MAP
+
"(BLOCK, LOB)"
);
stat
.
execute
(
"CREATE TABLE IF NOT EXISTS "
+
LOB_DATA
+
"(BLOCK BIGINT PRIMARY KEY, COMPRESSED INT,
HASH INT,
DATA BINARY) HIDDEN"
);
stat
.
execute
(
"CREATE TABLE IF NOT EXISTS "
+
LOB_DATA
+
"(BLOCK BIGINT PRIMARY KEY, COMPRESSED INT, DATA BINARY) HIDDEN"
);
ResultSet
rs
;
ResultSet
rs
;
rs
=
stat
.
executeQuery
(
"SELECT MAX(BLOCK) FROM "
+
LOB_DATA
);
rs
=
stat
.
executeQuery
(
"SELECT MAX(BLOCK) FROM "
+
LOB_DATA
);
rs
.
next
();
rs
.
next
();
...
@@ -268,19 +271,26 @@ public class LobStorage {
...
@@ -268,19 +271,26 @@ public class LobStorage {
private
void
deleteLob
(
long
lob
)
throws
SQLException
{
private
void
deleteLob
(
long
lob
)
throws
SQLException
{
PreparedStatement
prep
;
PreparedStatement
prep
;
prep
=
prepare
(
"SELECT BLOCK, HASH FROM "
+
LOB_MAP
+
" D WHERE D.LOB = ? "
+
"AND NOT EXISTS(SELECT 1 FROM "
+
LOB_MAP
+
" O "
+
"WHERE O.BLOCK = D.BLOCK AND O.LOB <> ?)"
);
prep
.
setLong
(
1
,
lob
);
prep
.
setLong
(
2
,
lob
);
ResultSet
rs
=
prep
.
executeQuery
();
prep
=
prepare
(
prep
=
prepare
(
"DELETE FROM "
+
LOB_MAP
+
" "
+
"DELETE FROM "
+
LOB_MAP
+
" "
+
"WHERE LOB = ?"
);
"WHERE LOB = ?"
);
prep
.
setLong
(
1
,
lob
);
prep
.
setLong
(
1
,
lob
);
prep
.
execute
();
prep
.
execute
();
prep
=
prepare
(
while
(
rs
.
next
())
{
"DELETE FROM "
+
LOB_DATA
+
" D "
+
long
block
=
rs
.
getLong
(
1
);
"WHERE BLOCK IN(SELECT M.BLOCK FROM "
+
LOB_MAP
+
" M WHERE LOB = ?) "
+
int
hash
=
rs
.
getInt
(
2
);
"AND NOT EXISTS(SELECT 1 FROM "
+
LOB_MAP
+
" M "
+
setHashCacheBlock
(
hash
,
-
1
);
"WHERE M.BLOCK = D.BLOCK AND M.LOB <> ?)"
);
prep
=
prepare
(
"DELETE FROM "
+
LOB_DATA
+
" WHERE BLOCK = ?"
);
prep
.
setLong
(
1
,
lob
);
prep
.
setLong
(
1
,
block
);
prep
.
setLong
(
2
,
lob
);
prep
.
execute
();
prep
.
execute
();
}
prep
=
prepare
(
prep
=
prepare
(
"DELETE FROM "
+
LOBS
+
" "
+
"DELETE FROM "
+
LOBS
+
" "
+
"WHERE ID = ?"
);
"WHERE ID = ?"
);
...
@@ -371,8 +381,8 @@ public class LobStorage {
...
@@ -371,8 +381,8 @@ public class LobStorage {
try
{
try
{
long
lobId
=
getNextLobId
();
long
lobId
=
getNextLobId
();
PreparedStatement
prep
=
prepare
(
PreparedStatement
prep
=
prepare
(
"INSERT INTO "
+
LOB_MAP
+
"(LOB, SEQ, BLOCK) "
+
"INSERT INTO "
+
LOB_MAP
+
"(LOB, SEQ,
HASH,
BLOCK) "
+
"SELECT ?, SEQ, BLOCK FROM "
+
LOB_MAP
+
" WHERE LOB = ?"
);
"SELECT ?, SEQ,
HASH,
BLOCK FROM "
+
LOB_MAP
+
" WHERE LOB = ?"
);
prep
.
setLong
(
1
,
lobId
);
prep
.
setLong
(
1
,
lobId
);
prep
.
setLong
(
2
,
oldLobId
);
prep
.
setLong
(
2
,
oldLobId
);
prep
.
executeUpdate
();
prep
.
executeUpdate
();
...
@@ -390,6 +400,25 @@ public class LobStorage {
...
@@ -390,6 +400,25 @@ public class LobStorage {
}
}
}
}
private
long
getHashCacheBlock
(
int
hash
)
{
if
(
HASH_CACHE_SIZE
>
0
)
{
int
index
=
(
int
)
(
hash
&
(
HASH_CACHE_SIZE
-
1
));
long
oldHash
=
hashBlocks
[
index
];
if
(
oldHash
==
hash
)
{
return
hashBlocks
[
index
+
HASH_CACHE_SIZE
];
}
}
return
-
1
;
}
private
void
setHashCacheBlock
(
int
hash
,
long
block
)
{
if
(
HASH_CACHE_SIZE
>
0
)
{
int
index
=
(
int
)
(
hash
&
(
HASH_CACHE_SIZE
-
1
));
hashBlocks
[
index
]
=
hash
;
hashBlocks
[
index
+
HASH_CACHE_SIZE
]
=
block
;
}
}
/**
/**
* Store a block in the LOB storage.
* Store a block in the LOB storage.
*
*
...
@@ -405,50 +434,37 @@ public class LobStorage {
...
@@ -405,50 +434,37 @@ public class LobStorage {
b
=
compress
.
compress
(
b
,
compressAlgorithm
);
b
=
compress
.
compress
(
b
,
compressAlgorithm
);
}
}
int
hash
=
Arrays
.
hashCode
(
b
);
int
hash
=
Arrays
.
hashCode
(
b
);
if
(
HASH
)
{
block
=
getHashCacheBlock
(
hash
);
block
=
0
;
if
(
block
!=
-
1
)
{
int
index
=
hash
&
(
HASH_CACHE_SIZE
-
1
);
long
oldHash
=
hashBlocks
[
index
];
int
hashTableAddWhenReading
;
int
hashTableRemoveWhenDeleting
;
if
(
oldHash
==
hash
)
{
long
old
=
hashBlocks
[
index
+
HASH_CACHE_SIZE
];
PreparedStatement
prep
=
prepare
(
PreparedStatement
prep
=
prepare
(
"SELECT COMPRESSED, DATA FROM "
+
LOB_DATA
+
"SELECT COMPRESSED, DATA FROM "
+
LOB_DATA
+
" WHERE BLOCK = ?"
);
" WHERE BLOCK = ?"
);
prep
.
setLong
(
1
,
old
);
prep
.
setLong
(
1
,
block
);
ResultSet
rs
=
prep
.
executeQuery
();
ResultSet
rs
=
prep
.
executeQuery
();
if
(
rs
.
next
())
{
if
(
rs
.
next
())
{
boolean
compressed
=
rs
.
getInt
(
1
)
!=
0
;
boolean
compressed
=
rs
.
getInt
(
1
)
!=
0
;
byte
[]
compare
=
rs
.
getBytes
(
2
);
byte
[]
compare
=
rs
.
getBytes
(
2
);
if
(
Arrays
.
equals
(
b
,
compare
)
&&
compressed
==
(
compressAlgorithm
!=
null
))
{
if
(
compressed
==
(
compressAlgorithm
!=
null
)
&&
Arrays
.
equals
(
b
,
compare
))
{
blockExists
=
true
;
blockExists
=
true
;
block
=
old
;
}
}
}
}
}
}
if
(!
blockExists
)
{
if
(!
blockExists
)
{
block
=
nextBlock
++;
block
=
nextBlock
++;
}
setHashCacheBlock
(
hash
,
block
);
hashBlocks
[
index
]
=
hash
;
hashBlocks
[
index
+
HASH_CACHE_SIZE
]
=
block
;
}
else
{
block
=
nextBlock
++;
}
if
(!
blockExists
)
{
PreparedStatement
prep
=
prepare
(
PreparedStatement
prep
=
prepare
(
"INSERT INTO "
+
LOB_DATA
+
"(BLOCK, COMPRESSED,
HASH, DATA) VALUES(?,
?, ?, ?)"
);
"INSERT INTO "
+
LOB_DATA
+
"(BLOCK, COMPRESSED,
DATA) VALUES(
?, ?, ?)"
);
prep
.
setLong
(
1
,
block
);
prep
.
setLong
(
1
,
block
);
prep
.
setInt
(
2
,
compressAlgorithm
==
null
?
0
:
1
);
prep
.
setInt
(
2
,
compressAlgorithm
==
null
?
0
:
1
);
prep
.
setInt
(
3
,
hash
);
prep
.
setBytes
(
3
,
b
);
prep
.
setBytes
(
4
,
b
);
prep
.
execute
();
prep
.
execute
();
}
}
PreparedStatement
prep
=
prepare
(
PreparedStatement
prep
=
prepare
(
"INSERT INTO "
+
LOB_MAP
+
"(LOB, SEQ,
BLOCK) VALUES(
?, ?, ?)"
);
"INSERT INTO "
+
LOB_MAP
+
"(LOB, SEQ,
HASH, BLOCK) VALUES(?,
?, ?, ?)"
);
prep
.
setLong
(
1
,
lobId
);
prep
.
setLong
(
1
,
lobId
);
prep
.
setInt
(
2
,
seq
);
prep
.
setInt
(
2
,
seq
);
prep
.
setLong
(
3
,
block
);
prep
.
setLong
(
3
,
hash
);
prep
.
setLong
(
4
,
block
);
prep
.
execute
();
prep
.
execute
();
}
}
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论