Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
6bdaf52a
提交
6bdaf52a
authored
15 年前
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
New experimental page store.
上级
37acb1ff
隐藏空白字符变更
内嵌
并排
正在显示
12 个修改的文件
包含
216 行增加
和
165 行删除
+216
-165
PageBtree.java
h2/src/main/org/h2/index/PageBtree.java
+19
-10
PageBtreeIndex.java
h2/src/main/org/h2/index/PageBtreeIndex.java
+1
-1
PageBtreeLeaf.java
h2/src/main/org/h2/index/PageBtreeLeaf.java
+16
-16
PageBtreeNode.java
h2/src/main/org/h2/index/PageBtreeNode.java
+66
-36
PageData.java
h2/src/main/org/h2/index/PageData.java
+7
-7
PageDataLeaf.java
h2/src/main/org/h2/index/PageDataLeaf.java
+10
-9
PageDataNode.java
h2/src/main/org/h2/index/PageDataNode.java
+5
-3
PageScanIndex.java
h2/src/main/org/h2/index/PageScanIndex.java
+2
-2
PageLog.java
h2/src/main/org/h2/store/PageLog.java
+7
-3
PageStore.java
h2/src/main/org/h2/store/PageStore.java
+1
-0
TestAll.java
h2/src/test/org/h2/test/TestAll.java
+0
-2
TestBtreeIndex.java
h2/src/test/org/h2/test/synth/TestBtreeIndex.java
+82
-76
没有找到文件。
h2/src/main/org/h2/index/PageBtree.java
浏览文件 @
6bdaf52a
...
...
@@ -94,9 +94,10 @@ abstract class PageBtree extends Record {
* @param compare the row
* @param bigger if looking for a larger row
* @param add if the row should be added (check for duplicate keys)
* @param compareKeys compare the row keys as well
* @return the index of the found row
*/
int
find
(
SearchRow
compare
,
boolean
bigger
,
boolean
add
)
throws
SQLException
{
int
find
(
SearchRow
compare
,
boolean
bigger
,
boolean
add
,
boolean
compareKeys
)
throws
SQLException
{
if
(
compare
==
null
)
{
return
0
;
}
...
...
@@ -106,13 +107,18 @@ abstract class PageBtree extends Record {
int
i
=
(
l
+
r
)
>>>
1
;
SearchRow
row
=
getRow
(
i
);
comp
=
index
.
compareRows
(
row
,
compare
);
if
(
comp
==
0
&&
add
)
{
if
(
index
.
indexType
.
isUnique
())
{
if
(
comp
==
0
)
{
if
(
add
&&
index
.
indexType
.
isUnique
())
{
if
(!
index
.
containsNullAndAllowMultipleNull
(
compare
))
{
throw
index
.
getDuplicateKeyException
();
}
}
comp
=
index
.
compareKeys
(
row
,
compare
);
if
(
compareKeys
)
{
comp
=
index
.
compareKeys
(
row
,
compare
);
if
(
comp
==
0
)
{
return
i
;
}
}
}
if
(
comp
>
0
||
(!
bigger
&&
comp
==
0
))
{
r
=
i
;
...
...
@@ -129,12 +135,13 @@ abstract class PageBtree extends Record {
abstract
void
read
()
throws
SQLException
;
/**
* Try to add a row.
* Add a row if possible. If it is possible this method returns -1, otherwise
* the split point. It is always possible to add one row.
*
* @param row the row
* @return 0 if successful, or the split position if the page needs to be
* split
* @param row the row to add
* @return the split point of this page, or -1 if no split is required
*/
abstract
int
addRowTry
(
SearchRow
row
)
throws
SQLException
;
/**
...
...
@@ -221,9 +228,11 @@ abstract class PageBtree extends Record {
* Remove a row.
*
* @param row the row to remove
* @return true if this page is now empty
* @return null if the last row didn't change,
* the deleted row if the page is now empty,
* otherwise the new last row of this page
*/
abstract
boolean
remove
(
SearchRow
row
)
throws
SQLException
;
abstract
SearchRow
remove
(
SearchRow
row
)
throws
SQLException
;
/**
* Free up all child pages.
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/index/PageBtreeIndex.java
浏览文件 @
6bdaf52a
...
...
@@ -87,7 +87,7 @@ public class PageBtreeIndex extends BaseIndex {
while
(
true
)
{
PageBtree
root
=
getPage
(
headPos
);
int
splitPoint
=
root
.
addRowTry
(
newRow
);
if
(
splitPoint
==
0
)
{
if
(
splitPoint
==
-
1
)
{
break
;
}
if
(
trace
.
isDebugEnabled
())
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/index/PageBtreeLeaf.java
浏览文件 @
6bdaf52a
...
...
@@ -54,20 +54,13 @@ class PageBtreeLeaf extends PageBtree {
start
=
data
.
length
();
}
/**
* Add a row if possible. If it is possible this method returns 0, otherwise
* the split point. It is always possible to add one row.
*
* @param row the now to add
* @return the split point of this page, or 0 if no split is required
*/
int
addRowTry
(
SearchRow
row
)
throws
SQLException
{
int
rowLength
=
index
.
getRowSize
(
data
,
row
,
onlyPosition
);
int
pageSize
=
index
.
getPageStore
().
getPageSize
();
int
last
=
entryCount
==
0
?
pageSize
:
offsets
[
entryCount
-
1
];
if
(
last
-
rowLength
<
start
+
OFFSET_LENGTH
)
{
if
(
entryCount
>
1
)
{
return
(
entryCount
/
2
)
+
1
;
return
entryCount
/
2
;
}
onlyPosition
=
true
;
// change the offsets (now storing only positions)
...
...
@@ -91,7 +84,7 @@ class PageBtreeLeaf extends PageBtree {
x
=
0
;
}
else
{
readAllRows
();
x
=
find
(
row
,
false
,
true
);
x
=
find
(
row
,
false
,
true
,
true
);
System
.
arraycopy
(
offsets
,
0
,
newOffsets
,
0
,
x
);
System
.
arraycopy
(
rows
,
0
,
newRows
,
0
,
x
);
if
(
x
<
entryCount
)
{
...
...
@@ -109,7 +102,7 @@ class PageBtreeLeaf extends PageBtree {
offsets
=
newOffsets
;
rows
=
newRows
;
index
.
getPageStore
().
updateRecord
(
this
,
true
,
data
);
return
0
;
return
-
1
;
}
private
void
removeRow
(
int
i
)
throws
SQLException
{
...
...
@@ -156,17 +149,24 @@ class PageBtreeLeaf extends PageBtree {
return
this
;
}
boolean
remove
(
SearchRow
row
)
throws
SQLException
{
int
at
=
find
(
row
,
false
,
false
);
if
(
index
.
compareRows
(
row
,
getRow
(
at
))
!=
0
)
{
SearchRow
remove
(
SearchRow
row
)
throws
SQLException
{
int
at
=
find
(
row
,
false
,
false
,
true
);
SearchRow
delete
=
getRow
(
at
);
if
(
index
.
compareRows
(
row
,
delete
)
!=
0
||
delete
.
getPos
()
!=
row
.
getPos
())
{
throw
Message
.
getSQLException
(
ErrorCode
.
ROW_NOT_FOUND_WHEN_DELETING_1
,
index
.
getSQL
()
+
": "
+
row
);
}
if
(
entryCount
==
1
)
{
return
true
;
// the page is now empty
return
row
;
}
removeRow
(
at
);
index
.
getPageStore
().
updateRecord
(
this
,
true
,
data
);
return
false
;
if
(
at
==
entryCount
)
{
// the last row changed
return
getRow
(
at
-
1
);
}
// the last row didn't change
return
null
;
}
void
freeChildren
()
{
...
...
@@ -210,7 +210,7 @@ class PageBtreeLeaf extends PageBtree {
}
void
find
(
PageBtreeCursor
cursor
,
SearchRow
first
,
boolean
bigger
)
throws
SQLException
{
int
i
=
find
(
first
,
bigger
,
false
);
int
i
=
find
(
first
,
bigger
,
false
,
false
);
if
(
i
>
entryCount
)
{
if
(
parentPageId
==
Page
.
ROOT
)
{
return
;
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/index/PageBtreeNode.java
浏览文件 @
6bdaf52a
...
...
@@ -16,16 +16,18 @@ import org.h2.store.PageStore;
import
org.h2.util.MemoryUtils
;
/**
* A b-tree node page that contains index data.
* Data is organized as follows: [leaf 0] (largest value of leaf 0) [leaf 1]
* Format:
* <ul><li>0-3: parent page id
* </li><li>4-4: page type
* </li><li>5-6: entry count
* </li><li>7-10: row count of all children (-1 if not known)
* </li><li>11-14: rightmost child page id
* </li><li>15- entries: 4 bytes leaf page id, 4 bytes offset to data
* </li></ul>
* A b-tree node page that contains index data. Data is organized as follows:
* [leaf 0] (largest value of leaf 0) [leaf 1] Format:
* <ul>
* <li>0-3: parent page id</li>
* <li>4-4: page type</li>
* <li>5-6: entry count</li>
* <li>7-10: row count of all children (-1 if not known)</li>
* <li>11-14: rightmost child page id</li>
* <li>15- entries: 4 bytes leaf page id, 4 bytes offset to data</li>
* </ul>
* The row is the largest row of the respective child, meaning
* row[0] is the largest row of child[0].
*/
class
PageBtreeNode
extends
PageBtree
{
...
...
@@ -37,7 +39,7 @@ class PageBtreeNode extends PageBtree {
*/
private
int
[]
childPageIds
;
//
private int rowCountStored = UNKNOWN_ROWCOUNT;
//
private int rowCountStored = UNKNOWN_ROWCOUNT;
private
int
rowCount
=
UNKNOWN_ROWCOUNT
;
...
...
@@ -67,25 +69,32 @@ class PageBtreeNode extends PageBtree {
start
=
data
.
length
();
}
/**
* Add a row. If it is possible this method returns -1, otherwise
* the split point. It is always possible to two rows.
*
* @param row the now to add
* @return the split point of this page, or -1 if no split is required
*/
private
int
addChildTry
(
SearchRow
row
)
throws
SQLException
{
if
(
entryCount
<
2
)
{
return
0
;
return
-
1
;
}
int
rowLength
=
index
.
getRowSize
(
data
,
row
,
onlyPosition
);
int
pageSize
=
index
.
getPageStore
().
getPageSize
();
int
last
=
entryCount
==
0
?
pageSize
:
offsets
[
entryCount
-
1
];
if
(
last
-
rowLength
<
start
+
CHILD_OFFSET_PAIR_LENGTH
)
{
return
(
entryCount
/
2
)
+
1
;
return
entryCount
/
2
;
}
return
0
;
return
-
1
;
}
/**
* Add a row. If it is possible this method returns 0, otherwise
* the split point. It is always possible to add one row.
* Add a child at the given position.
*
* @param row the now to add
* @return the split point of this page, or 0 if no split is required
* @param x the position
* @param childPageId the child
* @param row the row smaller than the first row of the child and its children
*/
private
void
addChild
(
int
x
,
int
childPageId
,
SearchRow
row
)
throws
SQLException
{
int
rowLength
=
index
.
getRowSize
(
data
,
row
,
onlyPosition
);
...
...
@@ -136,15 +145,15 @@ class PageBtreeNode extends PageBtree {
int
addRowTry
(
SearchRow
row
)
throws
SQLException
{
while
(
true
)
{
int
x
=
find
(
row
,
false
,
fals
e
);
int
x
=
find
(
row
,
false
,
true
,
tru
e
);
PageBtree
page
=
index
.
getPage
(
childPageIds
[
x
]);
int
splitPoint
=
page
.
addRowTry
(
row
);
if
(
splitPoint
==
0
)
{
if
(
splitPoint
==
-
1
)
{
break
;
}
SearchRow
pivot
=
page
.
getRow
(
splitPoint
-
1
);
int
splitPoint2
=
addChildTry
(
pivot
);
if
(
splitPoint2
!=
0
)
{
if
(
splitPoint2
!=
-
1
)
{
return
splitPoint2
;
}
PageBtree
page2
=
page
.
split
(
splitPoint
);
...
...
@@ -156,7 +165,7 @@ class PageBtreeNode extends PageBtree {
}
updateRowCount
(
1
);
written
=
false
;
return
0
;
return
-
1
;
}
private
void
updateRowCount
(
int
offset
)
{
...
...
@@ -215,7 +224,7 @@ class PageBtreeNode extends PageBtree {
}
void
find
(
PageBtreeCursor
cursor
,
SearchRow
first
,
boolean
bigger
)
throws
SQLException
{
int
i
=
find
(
first
,
bigger
,
false
);
int
i
=
find
(
first
,
bigger
,
false
,
false
);
if
(
i
>
entryCount
)
{
if
(
parentPageId
==
Page
.
ROOT
)
{
return
;
...
...
@@ -243,26 +252,48 @@ class PageBtreeNode extends PageBtree {
return
index
.
getPage
(
child
).
getLastLeaf
();
}
boolean
remove
(
SearchRow
row
)
throws
SQLException
{
int
at
=
find
(
row
,
false
,
false
);
SearchRow
remove
(
SearchRow
row
)
throws
SQLException
{
int
at
=
find
(
row
,
false
,
false
,
true
);
// merge is not implemented to allow concurrent usage
// TODO maybe implement merge
PageBtree
page
=
index
.
getPage
(
childPageIds
[
at
]);
boolean
empty
=
page
.
remove
(
row
);
SearchRow
last
=
page
.
remove
(
row
);
updateRowCount
(-
1
);
if
(!
empty
)
{
// the first row didn't change - nothing to do
return
false
;
if
(
last
==
null
)
{
// the last row didn't change - nothing to do
return
null
;
}
else
if
(
last
==
row
)
{
// this child is now empty
index
.
getPageStore
().
freePage
(
page
.
getPos
(),
true
,
page
.
data
);
if
(
entryCount
<
1
)
{
// no more children - this page is empty as well
return
row
;
}
if
(
at
==
entryCount
)
{
// removing the last child
last
=
getRow
(
at
-
1
);
}
else
{
last
=
null
;
}
removeChild
(
at
);
index
.
getPageStore
().
updateRecord
(
this
,
true
,
data
);
return
last
;
}
// this child is now empty
index
.
getPageStore
().
freePage
(
page
.
getPos
(),
true
,
page
.
data
);
if
(
entryCount
<
1
)
{
// no more children - this page is empty as well
return
true
;
// the last row is in the last child
if
(
at
==
entryCount
)
{
return
last
;
}
int
child
=
childPageIds
[
at
];
removeChild
(
at
);
// TODO this can mean only the position is now stored
// should split at the next possible moment
addChild
(
at
,
child
,
last
);
// remove and add swapped two children, fix that
int
temp
=
childPageIds
[
at
];
childPageIds
[
at
]
=
childPageIds
[
at
+
1
];
childPageIds
[
at
+
1
]
=
temp
;
index
.
getPageStore
().
updateRecord
(
this
,
true
,
data
);
return
false
;
return
null
;
}
int
getRowCount
()
throws
SQLException
{
...
...
@@ -420,5 +451,4 @@ class PageBtreeNode extends PageBtree {
return
"page["
+
getPos
()
+
"] b-tree node table:"
+
index
.
getId
()
+
" entries:"
+
entryCount
;
}
}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/index/PageData.java
浏览文件 @
6bdaf52a
...
...
@@ -84,10 +84,10 @@ abstract class PageData extends Record {
while
(
l
<
r
)
{
int
i
=
(
l
+
r
)
>>>
1
;
int
k
=
keys
[
i
];
if
(
k
>
key
)
{
r
=
i
;
}
else
if
(
k
==
key
)
{
if
(
k
==
key
)
{
return
i
;
}
else
if
(
k
>
key
)
{
r
=
i
;
}
else
{
l
=
i
+
1
;
}
...
...
@@ -101,11 +101,11 @@ abstract class PageData extends Record {
abstract
void
read
()
throws
SQLException
;
/**
* Try to add a row.
* Add a row if possible. If it is possible this method returns -1, otherwise
* the split point. It is always possible to add one row.
*
* @param row the row
* @return 0 if successful, or the split position if the page needs to be
* split
* @param row the now to add
* @return the split point of this page, or -1 if no split is required
*/
abstract
int
addRowTry
(
Row
row
)
throws
SQLException
;
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/index/PageDataLeaf.java
浏览文件 @
6bdaf52a
...
...
@@ -92,19 +92,20 @@ class PageDataLeaf extends PageData {
start
=
data
.
length
();
}
/**
* Add a row if possible. If it is possible this method returns 0, otherwise
* the split point. It is always possible to add one row.
*
* @param row the now to add
* @return the split point of this page, or 0 if no split is required
*/
int
addRowTry
(
Row
row
)
throws
SQLException
{
int
rowLength
=
row
.
getByteCount
(
data
);
int
pageSize
=
index
.
getPageStore
().
getPageSize
();
int
last
=
entryCount
==
0
?
pageSize
:
offsets
[
entryCount
-
1
];
if
(
entryCount
>
0
&&
last
-
rowLength
<
start
+
KEY_OFFSET_PAIR_LENGTH
)
{
return
(
entryCount
/
2
)
+
1
;
if
(
entryCount
>
1
)
{
return
entryCount
/
2
;
}
int
todoIncorrect
;
if
(
find
(
row
.
getPos
())
!=
1
)
{
System
.
out
.
println
(
"todo "
+
find
(
row
.
getPos
()));
}
return
1
;
// find(row.getPos()) + 1;
}
int
offset
=
last
-
rowLength
;
int
[]
newOffsets
=
new
int
[
entryCount
+
1
];
...
...
@@ -181,7 +182,7 @@ class PageDataLeaf extends PageData {
}
while
(
remaining
>
0
);
data
.
truncate
(
index
.
getPageStore
().
getPageSize
());
}
return
0
;
return
-
1
;
}
private
void
removeRow
(
int
i
)
throws
SQLException
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/index/PageDataNode.java
浏览文件 @
6bdaf52a
...
...
@@ -25,6 +25,8 @@ import org.h2.util.MemoryUtils;
* </li><li>11-14: rightmost child page id
* </li><li>15- entries: 4 bytes leaf page id, 4 bytes key
* </li></ul>
* The key is the largest key of the respective child, meaning
* key[0] is the largest key of child[0].
*/
class
PageDataNode
extends
PageData
{
...
...
@@ -85,14 +87,14 @@ class PageDataNode extends PageData {
int
x
=
find
(
row
.
getPos
());
PageData
page
=
index
.
getPage
(
childPageIds
[
x
],
getPos
());
int
splitPoint
=
page
.
addRowTry
(
row
);
if
(
splitPoint
==
0
)
{
if
(
splitPoint
==
-
1
)
{
break
;
}
int
maxEntries
=
(
index
.
getPageStore
().
getPageSize
()
-
ENTRY_START
)
/
ENTRY_LENGTH
;
if
(
entryCount
>=
maxEntries
)
{
return
entryCount
/
2
;
}
int
pivot
=
page
.
getKey
(
splitPoint
-
1
);
int
pivot
=
splitPoint
==
0
?
row
.
getPos
()
:
page
.
getKey
(
splitPoint
-
1
);
PageData
page2
=
page
.
split
(
splitPoint
);
index
.
getPageStore
().
updateRecord
(
page
,
true
,
page
.
data
);
index
.
getPageStore
().
updateRecord
(
page2
,
true
,
page2
.
data
);
...
...
@@ -100,7 +102,7 @@ class PageDataNode extends PageData {
index
.
getPageStore
().
updateRecord
(
this
,
true
,
data
);
}
updateRowCount
(
1
);
return
0
;
return
-
1
;
}
private
void
updateRowCount
(
int
offset
)
throws
SQLException
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/index/PageScanIndex.java
浏览文件 @
6bdaf52a
...
...
@@ -115,13 +115,13 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
while
(
true
)
{
PageData
root
=
getPage
(
headPos
,
0
);
int
splitPoint
=
root
.
addRowTry
(
row
);
if
(
splitPoint
==
0
)
{
if
(
splitPoint
==
-
1
)
{
break
;
}
if
(
trace
.
isDebugEnabled
())
{
trace
.
debug
(
"split "
+
splitPoint
);
}
int
pivot
=
root
.
getKey
(
splitPoint
-
1
);
int
pivot
=
splitPoint
==
0
?
row
.
getPos
()
:
root
.
getKey
(
splitPoint
-
1
);
PageData
page1
=
root
;
PageData
page2
=
root
.
split
(
splitPoint
);
int
rootPageId
=
root
.
getPos
();
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/store/PageLog.java
浏览文件 @
6bdaf52a
...
...
@@ -216,10 +216,13 @@ public class PageLog {
int
pageId
=
in
.
readInt
();
in
.
readFully
(
data
.
getBytes
(),
0
,
store
.
getPageSize
());
if
(
stage
==
RECOVERY_STAGE_UNDO
)
{
if
(
trace
.
isDebugEnabled
())
{
trace
.
debug
(
"log undo "
+
pageId
);
if
(!
undo
.
get
(
pageId
))
{
if
(
trace
.
isDebugEnabled
())
{
trace
.
debug
(
"log undo "
+
pageId
);
}
store
.
writePage
(
pageId
,
data
);
undo
.
set
(
pageId
);
}
store
.
writePage
(
pageId
,
data
);
}
}
else
if
(
x
==
ADD
||
x
==
REMOVE
)
{
int
sessionId
=
in
.
readInt
();
...
...
@@ -288,6 +291,7 @@ public class PageLog {
}
catch
(
IOException
e
)
{
throw
Message
.
convertIOException
(
e
,
"recover"
);
}
undo
=
new
BitField
();
}
/**
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/store/PageStore.java
浏览文件 @
6bdaf52a
...
...
@@ -103,6 +103,7 @@ public class PageStore implements CacheWriter {
// TODO update: only log the key and changed values
// TODO store dates differently in Data; test moving db to another timezone
// TODO online backup using bsdiff
// TODO trying to insert duplicate key can split a page: not in recovery
// TODO when removing DiskFile:
// remove CacheObject.blockCount
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/TestAll.java
浏览文件 @
6bdaf52a
...
...
@@ -295,8 +295,6 @@ java org.h2.test.TestAll timer
/*
page store: TestBtreeIndex
-------------
create a short documentation
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/synth/TestBtreeIndex.java
浏览文件 @
6bdaf52a
...
...
@@ -41,24 +41,27 @@ public class TestBtreeIndex extends TestBase {
private
void
testAddDelete
()
throws
SQLException
{
deleteDb
(
"index"
);
Connection
conn
=
getConnection
(
"index"
);
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST(ID bigint primary key)"
);
int
count
=
1000
;
stat
.
execute
(
"insert into test select x from system_range(1, "
+
count
+
")"
);
if
(!
config
.
memory
)
{
conn
.
close
();
conn
=
getConnection
(
"index"
);
stat
=
conn
.
createStatement
();
}
for
(
int
i
=
1
;
i
<
count
;
i
++)
{
ResultSet
rs
=
stat
.
executeQuery
(
"select * from test order by id"
);
for
(
int
j
=
i
;
rs
.
next
();
j
++)
{
assertEquals
(
j
,
rs
.
getInt
(
1
));
try
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST(ID bigint primary key)"
);
int
count
=
1000
;
stat
.
execute
(
"insert into test select x from system_range(1, "
+
count
+
")"
);
if
(!
config
.
memory
)
{
conn
.
close
();
conn
=
getConnection
(
"index"
);
stat
=
conn
.
createStatement
();
}
stat
.
execute
(
"delete from test where id ="
+
i
);
for
(
int
i
=
1
;
i
<
count
;
i
++)
{
ResultSet
rs
=
stat
.
executeQuery
(
"select * from test order by id"
);
for
(
int
j
=
i
;
rs
.
next
();
j
++)
{
assertEquals
(
j
,
rs
.
getInt
(
1
));
}
stat
.
execute
(
"delete from test where id ="
+
i
);
}
stat
.
execute
(
"drop all objects delete files"
);
}
finally
{
conn
.
close
();
}
stat
.
execute
(
"drop all objects delete files"
);
conn
.
close
();
}
public
void
testCase
(
int
seed
)
throws
SQLException
{
...
...
@@ -92,75 +95,78 @@ public class TestBtreeIndex extends TestBase {
String
prefix
=
buff
.
toString
();
DeleteDbFiles
.
execute
(
baseDir
,
null
,
true
);
Connection
conn
=
getConnection
(
"index"
);
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE a(text VARCHAR PRIMARY KEY)"
);
PreparedStatement
prepInsert
=
conn
.
prepareStatement
(
"INSERT INTO a VALUES(?)"
);
PreparedStatement
prepDelete
=
conn
.
prepareStatement
(
"DELETE FROM a WHERE text=?"
);
PreparedStatement
prepDeleteAllButOne
=
conn
.
prepareStatement
(
"DELETE FROM a WHERE text <> ?"
);
int
count
=
0
;
for
(
int
i
=
0
;
i
<
1000
;
i
++)
{
int
y
=
random
.
nextInt
(
distinct
);
try
{
prepInsert
.
setString
(
1
,
prefix
+
y
);
prepInsert
.
executeUpdate
();
count
++;
}
catch
(
SQLException
e
)
{
if
(
e
.
getSQLState
().
equals
(
"23001"
))
{
// ignore
}
else
{
TestBase
.
logError
(
"error"
,
e
);
break
;
}
}
if
(
delete
&&
random
.
nextInt
(
10
)
==
1
)
{
if
(
random
.
nextInt
(
4
)
==
1
)
{
try
{
prepDeleteAllButOne
.
setString
(
1
,
prefix
+
y
);
int
deleted
=
prepDeleteAllButOne
.
executeUpdate
();
if
(
deleted
<
count
-
1
)
{
printError
(
seed
,
"deleted:"
+
deleted
);
}
count
-=
deleted
;
}
catch
(
SQLException
e
)
{
try
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE a(text VARCHAR PRIMARY KEY)"
);
PreparedStatement
prepInsert
=
conn
.
prepareStatement
(
"INSERT INTO a VALUES(?)"
);
PreparedStatement
prepDelete
=
conn
.
prepareStatement
(
"DELETE FROM a WHERE text=?"
);
PreparedStatement
prepDeleteAllButOne
=
conn
.
prepareStatement
(
"DELETE FROM a WHERE text <> ?"
);
int
count
=
0
;
for
(
int
i
=
0
;
i
<
1000
;
i
++)
{
int
y
=
random
.
nextInt
(
distinct
);
try
{
prepInsert
.
setString
(
1
,
prefix
+
y
);
prepInsert
.
executeUpdate
();
count
++;
}
catch
(
SQLException
e
)
{
if
(
e
.
getSQLState
().
equals
(
"23001"
))
{
// ignore
}
else
{
TestBase
.
logError
(
"error"
,
e
);
break
;
}
}
else
{
try
{
prepDelete
.
setString
(
1
,
prefix
+
y
);
int
deleted
=
prepDelete
.
executeUpdate
();
if
(
deleted
>
1
)
{
printError
(
seed
,
"deleted:"
+
deleted
);
}
if
(
delete
&&
random
.
nextInt
(
10
)
==
1
)
{
if
(
random
.
nextInt
(
4
)
==
1
)
{
try
{
prepDeleteAllButOne
.
setString
(
1
,
prefix
+
y
);
int
deleted
=
prepDeleteAllButOne
.
executeUpdate
();
if
(
deleted
<
count
-
1
)
{
printError
(
seed
,
"deleted:"
+
deleted
+
" i:"
+
i
);
}
count
-=
deleted
;
}
catch
(
SQLException
e
)
{
TestBase
.
logError
(
"error"
,
e
);
break
;
}
}
else
{
try
{
prepDelete
.
setString
(
1
,
prefix
+
y
);
int
deleted
=
prepDelete
.
executeUpdate
();
if
(
deleted
>
1
)
{
printError
(
seed
,
"deleted:"
+
deleted
+
" i:"
+
i
);
}
count
-=
deleted
;
}
catch
(
SQLException
e
)
{
TestBase
.
logError
(
"error"
,
e
);
break
;
}
count
-=
deleted
;
}
catch
(
SQLException
e
)
{
TestBase
.
logError
(
"error"
,
e
);
break
;
}
}
}
}
int
testCount
;
testCount
=
0
;
ResultSet
rs
=
stat
.
executeQuery
(
"SELECT text FROM a ORDER BY text"
);
ResultSet
rs2
=
conn
.
createStatement
().
executeQuery
(
"SELECT text FROM a ORDER BY 'x' || text"
);
testCount
=
0
;
while
(
rs
.
next
()
&&
rs2
.
next
())
{
if
(!
rs
.
getString
(
1
).
equals
(
rs2
.
getString
(
1
)))
{
fail
(
""
+
testCount
);
int
testCount
;
testCount
=
0
;
ResultSet
rs
=
stat
.
executeQuery
(
"SELECT text FROM a ORDER BY text"
);
ResultSet
rs2
=
conn
.
createStatement
().
executeQuery
(
"SELECT text FROM a ORDER BY 'x' || text"
);
testCount
=
0
;
while
(
rs
.
next
()
&&
rs2
.
next
())
{
if
(!
rs
.
getString
(
1
).
equals
(
rs2
.
getString
(
1
)))
{
fail
(
""
+
testCount
);
}
testCount
++;
}
testCount
++;
}
assertFalse
(
rs
.
next
());
assertFalse
(
rs2
.
next
());
if
(
testCount
!=
count
)
{
printError
(
seed
,
"count:"
+
count
+
" testCount:"
+
testCount
);
}
rs
=
stat
.
executeQuery
(
"SELECT text, count(*) FROM a GROUP BY text HAVING COUNT(*)>1"
);
if
(
rs
.
next
())
{
printError
(
seed
,
"testCount:"
+
testCount
);
assertFalse
(
rs
.
next
());
assertFalse
(
rs2
.
next
());
if
(
testCount
!=
count
)
{
printError
(
seed
,
"count:"
+
count
+
" testCount:"
+
testCount
);
}
rs
=
stat
.
executeQuery
(
"SELECT text, count(*) FROM a GROUP BY text HAVING COUNT(*)>1"
);
if
(
rs
.
next
())
{
printError
(
seed
,
"testCount:"
+
testCount
+
" "
+
rs
.
getString
(
1
));
}
}
finally
{
conn
.
close
();
}
conn
.
close
();
}
private
void
printError
(
int
seed
,
String
message
)
{
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论