Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
7c23654a
提交
7c23654a
authored
15 年前
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
New experimental page store.
上级
225e8ba1
隐藏空白字符变更
内嵌
并排
正在显示
17 个修改的文件
包含
338 行增加
和
407 行删除
+338
-407
Database.java
h2/src/main/org/h2/engine/Database.java
+3
-1
PageBtree.java
h2/src/main/org/h2/index/PageBtree.java
+14
-0
PageBtreeCursor.java
h2/src/main/org/h2/index/PageBtreeCursor.java
+12
-3
PageBtreeIndex.java
h2/src/main/org/h2/index/PageBtreeIndex.java
+30
-4
PageBtreeLeaf.java
h2/src/main/org/h2/index/PageBtreeLeaf.java
+23
-1
PageBtreeNode.java
h2/src/main/org/h2/index/PageBtreeNode.java
+50
-5
PageScanIndex.java
h2/src/main/org/h2/index/PageScanIndex.java
+0
-3
LogSystem.java
h2/src/main/org/h2/log/LogSystem.java
+3
-9
Message.java
h2/src/main/org/h2/message/Message.java
+4
-0
PageLog.java
h2/src/main/org/h2/store/PageLog.java
+6
-12
PageOutputStream.java
h2/src/main/org/h2/store/PageOutputStream.java
+28
-0
PageStore.java
h2/src/main/org/h2/store/PageStore.java
+147
-100
PageStreamTrunk.java
h2/src/main/org/h2/store/PageStreamTrunk.java
+6
-1
TestAll.java
h2/src/test/org/h2/test/TestAll.java
+3
-0
TestPowerOff.java
h2/src/test/org/h2/test/db/TestPowerOff.java
+2
-1
TestPageStore.java
h2/src/test/org/h2/test/unit/TestPageStore.java
+0
-266
TestRecovery.java
h2/src/test/org/h2/test/unit/TestRecovery.java
+7
-1
没有找到文件。
h2/src/main/org/h2/engine/Database.java
浏览文件 @
7c23654a
...
@@ -2345,7 +2345,9 @@ public class Database implements DataHandler {
...
@@ -2345,7 +2345,9 @@ public class Database implements DataHandler {
*/
*/
public
void
checkpoint
()
throws
SQLException
{
public
void
checkpoint
()
throws
SQLException
{
if
(
SysProperties
.
PAGE_STORE
)
{
if
(
SysProperties
.
PAGE_STORE
)
{
pageStore
.
checkpoint
();
if
(
persistent
)
{
pageStore
.
checkpoint
();
}
}
}
getLog
().
checkpoint
();
getLog
().
checkpoint
();
getTempFileDeleter
().
deleteUnused
();
getTempFileDeleter
().
deleteUnused
();
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/index/PageBtree.java
浏览文件 @
7c23654a
...
@@ -145,6 +145,13 @@ abstract class PageBtree extends Record {
...
@@ -145,6 +145,13 @@ abstract class PageBtree extends Record {
*/
*/
abstract
void
find
(
PageBtreeCursor
cursor
,
SearchRow
first
,
boolean
bigger
)
throws
SQLException
;
abstract
void
find
(
PageBtreeCursor
cursor
,
SearchRow
first
,
boolean
bigger
)
throws
SQLException
;
/**
* Find the last row.
*
* @param cursor the cursor
*/
abstract
void
last
(
PageBtreeCursor
cursor
)
throws
SQLException
;
/**
/**
* Get the row at this position.
* Get the row at this position.
*
*
...
@@ -190,6 +197,13 @@ abstract class PageBtree extends Record {
...
@@ -190,6 +197,13 @@ abstract class PageBtree extends Record {
*/
*/
abstract
PageBtreeLeaf
getFirstLeaf
()
throws
SQLException
;
abstract
PageBtreeLeaf
getFirstLeaf
()
throws
SQLException
;
/**
* Get the first child leaf page of a page.
*
* @return the page
*/
abstract
PageBtreeLeaf
getLastLeaf
()
throws
SQLException
;
/**
/**
* Change the parent page id.
* Change the parent page id.
*
*
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/index/PageBtreeCursor.java
浏览文件 @
7c23654a
...
@@ -62,7 +62,6 @@ public class PageBtreeCursor implements Cursor {
...
@@ -62,7 +62,6 @@ public class PageBtreeCursor implements Cursor {
}
}
if
(
i
>=
current
.
getEntryCount
())
{
if
(
i
>=
current
.
getEntryCount
())
{
current
.
nextPage
(
this
);
current
.
nextPage
(
this
);
i
=
0
;
if
(
current
==
null
)
{
if
(
current
==
null
)
{
return
false
;
return
false
;
}
}
...
@@ -77,9 +76,19 @@ public class PageBtreeCursor implements Cursor {
...
@@ -77,9 +76,19 @@ public class PageBtreeCursor implements Cursor {
return
true
;
return
true
;
}
}
public
boolean
previous
()
{
public
boolean
previous
()
throws
SQLException
{
if
(
current
==
null
)
{
return
false
;
}
if
(
i
<=
0
)
{
current
.
previousPage
(
this
);
if
(
current
==
null
)
{
return
false
;
}
}
currentSearchRow
=
current
.
getRow
(
i
);
currentRow
=
null
;
i
--;
i
--;
int
todo
;
return
true
;
return
true
;
}
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/index/PageBtreeIndex.java
浏览文件 @
7c23654a
...
@@ -21,6 +21,7 @@ import org.h2.table.IndexColumn;
...
@@ -21,6 +21,7 @@ import org.h2.table.IndexColumn;
import
org.h2.table.TableData
;
import
org.h2.table.TableData
;
import
org.h2.value.Value
;
import
org.h2.value.Value
;
import
org.h2.value.ValueLob
;
import
org.h2.value.ValueLob
;
import
org.h2.value.ValueNull
;
/**
/**
* This is the most common type of index, a b tree index.
* This is the most common type of index, a b tree index.
...
@@ -152,7 +153,7 @@ public class PageBtreeIndex extends BaseIndex {
...
@@ -152,7 +153,7 @@ public class PageBtreeIndex extends BaseIndex {
}
}
public
boolean
canGetFirstOrLast
()
{
public
boolean
canGetFirstOrLast
()
{
return
fals
e
;
return
tru
e
;
}
}
public
Cursor
findNext
(
Session
session
,
SearchRow
first
,
SearchRow
last
)
throws
SQLException
{
public
Cursor
findNext
(
Session
session
,
SearchRow
first
,
SearchRow
last
)
throws
SQLException
{
...
@@ -174,7 +175,34 @@ public class PageBtreeIndex extends BaseIndex {
...
@@ -174,7 +175,34 @@ public class PageBtreeIndex extends BaseIndex {
}
}
public
Cursor
findFirstOrLast
(
Session
session
,
boolean
first
)
throws
SQLException
{
public
Cursor
findFirstOrLast
(
Session
session
,
boolean
first
)
throws
SQLException
{
throw
Message
.
getUnsupportedException
(
"PAGE"
);
if
(
first
)
{
// TODO optimization: this loops through NULL elements
Cursor
cursor
=
find
(
session
,
null
,
false
,
null
);
while
(
cursor
.
next
())
{
SearchRow
row
=
cursor
.
getSearchRow
();
Value
v
=
row
.
getValue
(
columnIds
[
0
]);
if
(
v
!=
ValueNull
.
INSTANCE
)
{
return
cursor
;
}
}
return
cursor
;
}
PageBtree
root
=
getPage
(
headPos
);
PageBtreeCursor
cursor
=
new
PageBtreeCursor
(
session
,
this
,
null
);
root
.
last
(
cursor
);
cursor
.
previous
();
// TODO optimization: this loops through NULL elements
do
{
SearchRow
row
=
cursor
.
getSearchRow
();
if
(
row
==
null
)
{
break
;
}
Value
v
=
row
.
getValue
(
columnIds
[
0
]);
if
(
v
!=
ValueNull
.
INSTANCE
)
{
return
cursor
;
}
}
while
(
cursor
.
previous
());
return
cursor
;
}
}
public
double
getCost
(
Session
session
,
int
[]
masks
)
{
public
double
getCost
(
Session
session
,
int
[]
masks
)
{
...
@@ -278,8 +306,6 @@ public class PageBtreeIndex extends BaseIndex {
...
@@ -278,8 +306,6 @@ public class PageBtreeIndex extends BaseIndex {
if
(
trace
.
isDebugEnabled
())
{
if
(
trace
.
isDebugEnabled
())
{
trace
.
debug
(
"close"
);
trace
.
debug
(
"close"
);
}
}
int
todoWhyRequired
;
// store = null;
int
writeRowCount
;
int
writeRowCount
;
}
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/index/PageBtreeLeaf.java
浏览文件 @
7c23654a
...
@@ -65,7 +65,7 @@ class PageBtreeLeaf extends PageBtree {
...
@@ -65,7 +65,7 @@ class PageBtreeLeaf extends PageBtree {
int
pageSize
=
index
.
getPageStore
().
getPageSize
();
int
pageSize
=
index
.
getPageStore
().
getPageSize
();
int
last
=
entryCount
==
0
?
pageSize
:
offsets
[
entryCount
-
1
];
int
last
=
entryCount
==
0
?
pageSize
:
offsets
[
entryCount
-
1
];
if
(
last
-
rowLength
<
start
+
OFFSET_LENGTH
)
{
if
(
last
-
rowLength
<
start
+
OFFSET_LENGTH
)
{
if
(
entryCount
>
0
)
{
if
(
entryCount
>
1
)
{
int
todoSplitAtLastInsertionPoint
;
int
todoSplitAtLastInsertionPoint
;
return
(
entryCount
/
2
)
+
1
;
return
(
entryCount
/
2
)
+
1
;
}
}
...
@@ -142,6 +142,10 @@ class PageBtreeLeaf extends PageBtree {
...
@@ -142,6 +142,10 @@ class PageBtreeLeaf extends PageBtree {
return
this
;
return
this
;
}
}
PageBtreeLeaf
getLastLeaf
()
{
return
this
;
}
boolean
remove
(
SearchRow
row
)
throws
SQLException
{
boolean
remove
(
SearchRow
row
)
throws
SQLException
{
int
at
=
find
(
row
,
false
,
false
);
int
at
=
find
(
row
,
false
,
false
);
if
(
index
.
compareRows
(
row
,
getRow
(
at
))
!=
0
)
{
if
(
index
.
compareRows
(
row
,
getRow
(
at
))
!=
0
)
{
...
@@ -213,6 +217,10 @@ class PageBtreeLeaf extends PageBtree {
...
@@ -213,6 +217,10 @@ class PageBtreeLeaf extends PageBtree {
cursor
.
setCurrent
(
this
,
i
);
cursor
.
setCurrent
(
this
,
i
);
}
}
void
last
(
PageBtreeCursor
cursor
)
{
cursor
.
setCurrent
(
this
,
entryCount
-
1
);
}
void
remapChildren
()
{
void
remapChildren
()
{
}
}
...
@@ -230,6 +238,20 @@ class PageBtreeLeaf extends PageBtree {
...
@@ -230,6 +238,20 @@ class PageBtreeLeaf extends PageBtree {
next
.
nextPage
(
cursor
,
getPos
());
next
.
nextPage
(
cursor
,
getPos
());
}
}
/**
* Set the cursor to the last row of the previous page.
*
* @param cursor the cursor
*/
void
previousPage
(
PageBtreeCursor
cursor
)
throws
SQLException
{
if
(
parentPageId
==
Page
.
ROOT
)
{
cursor
.
setCurrent
(
null
,
0
);
return
;
}
PageBtreeNode
next
=
(
PageBtreeNode
)
index
.
getPage
(
parentPageId
);
next
.
previousPage
(
cursor
,
getPos
());
}
public
String
toString
()
{
public
String
toString
()
{
return
"page["
+
getPos
()
+
"] btree leaf table:"
+
index
.
getId
()
+
" entries:"
+
entryCount
;
return
"page["
+
getPos
()
+
"] btree leaf table:"
+
index
.
getId
()
+
" entries:"
+
entryCount
;
}
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/index/PageBtreeNode.java
浏览文件 @
7c23654a
...
@@ -61,7 +61,7 @@ class PageBtreeNode extends PageBtree {
...
@@ -61,7 +61,7 @@ class PageBtreeNode extends PageBtree {
}
}
private
int
addChildTry
(
SearchRow
row
)
throws
SQLException
{
private
int
addChildTry
(
SearchRow
row
)
throws
SQLException
{
if
(
entryCount
==
0
)
{
if
(
entryCount
<
2
)
{
return
0
;
return
0
;
}
}
int
rowLength
=
index
.
getRowSize
(
data
,
row
,
onlyPosition
);
int
rowLength
=
index
.
getRowSize
(
data
,
row
,
onlyPosition
);
...
@@ -86,9 +86,7 @@ class PageBtreeNode extends PageBtree {
...
@@ -86,9 +86,7 @@ class PageBtreeNode extends PageBtree {
int
pageSize
=
index
.
getPageStore
().
getPageSize
();
int
pageSize
=
index
.
getPageStore
().
getPageSize
();
int
last
=
entryCount
==
0
?
pageSize
:
offsets
[
entryCount
-
1
];
int
last
=
entryCount
==
0
?
pageSize
:
offsets
[
entryCount
-
1
];
if
(
last
-
rowLength
<
start
+
CHILD_OFFSET_PAIR_LENGTH
)
{
if
(
last
-
rowLength
<
start
+
CHILD_OFFSET_PAIR_LENGTH
)
{
if
(
entryCount
>
0
)
{
// TODO remap all children
throw
Message
.
throwInternalError
();
}
onlyPosition
=
true
;
onlyPosition
=
true
;
rowLength
=
index
.
getRowSize
(
data
,
row
,
onlyPosition
);
rowLength
=
index
.
getRowSize
(
data
,
row
,
onlyPosition
);
}
}
...
@@ -132,7 +130,7 @@ class PageBtreeNode extends PageBtree {
...
@@ -132,7 +130,7 @@ class PageBtreeNode extends PageBtree {
SearchRow
pivot
=
page
.
getRow
(
splitPoint
-
1
);
SearchRow
pivot
=
page
.
getRow
(
splitPoint
-
1
);
int
splitPoint2
=
addChildTry
(
pivot
);
int
splitPoint2
=
addChildTry
(
pivot
);
if
(
splitPoint2
!=
0
)
{
if
(
splitPoint2
!=
0
)
{
return
splitPoint
;
return
splitPoint
2
;
}
}
PageBtree
page2
=
page
.
split
(
splitPoint
);
PageBtree
page2
=
page
.
split
(
splitPoint
);
addChild
(
x
,
page2
.
getPageId
(),
pivot
);
addChild
(
x
,
page2
.
getPageId
(),
pivot
);
...
@@ -158,6 +156,10 @@ class PageBtreeNode extends PageBtree {
...
@@ -158,6 +156,10 @@ class PageBtreeNode extends PageBtree {
PageBtree
split
(
int
splitPoint
)
throws
SQLException
{
PageBtree
split
(
int
splitPoint
)
throws
SQLException
{
int
newPageId
=
index
.
getPageStore
().
allocatePage
();
int
newPageId
=
index
.
getPageStore
().
allocatePage
();
PageBtreeNode
p2
=
new
PageBtreeNode
(
index
,
newPageId
,
parentPageId
,
index
.
getPageStore
().
createDataPage
());
PageBtreeNode
p2
=
new
PageBtreeNode
(
index
,
newPageId
,
parentPageId
,
index
.
getPageStore
().
createDataPage
());
if
(
onlyPosition
)
{
// TODO optimize: maybe not required
p2
.
onlyPosition
=
true
;
}
int
firstChild
=
childPageIds
[
splitPoint
];
int
firstChild
=
childPageIds
[
splitPoint
];
for
(
int
i
=
splitPoint
;
i
<
entryCount
;)
{
for
(
int
i
=
splitPoint
;
i
<
entryCount
;)
{
p2
.
addChild
(
p2
.
entryCount
,
childPageIds
[
splitPoint
+
1
],
rows
[
splitPoint
]);
p2
.
addChild
(
p2
.
entryCount
,
childPageIds
[
splitPoint
+
1
],
rows
[
splitPoint
]);
...
@@ -166,6 +168,9 @@ class PageBtreeNode extends PageBtree {
...
@@ -166,6 +168,9 @@ class PageBtreeNode extends PageBtree {
int
lastChild
=
childPageIds
[
splitPoint
-
1
];
int
lastChild
=
childPageIds
[
splitPoint
-
1
];
removeChild
(
splitPoint
-
1
);
removeChild
(
splitPoint
-
1
);
childPageIds
[
splitPoint
-
1
]
=
lastChild
;
childPageIds
[
splitPoint
-
1
]
=
lastChild
;
if
(
p2
.
childPageIds
==
null
)
{
p2
.
childPageIds
=
new
int
[
1
];
}
p2
.
childPageIds
[
0
]
=
firstChild
;
p2
.
childPageIds
[
0
]
=
firstChild
;
p2
.
remapChildren
();
p2
.
remapChildren
();
return
p2
;
return
p2
;
...
@@ -209,11 +214,21 @@ class PageBtreeNode extends PageBtree {
...
@@ -209,11 +214,21 @@ class PageBtreeNode extends PageBtree {
page
.
find
(
cursor
,
first
,
bigger
);
page
.
find
(
cursor
,
first
,
bigger
);
}
}
void
last
(
PageBtreeCursor
cursor
)
throws
SQLException
{
int
child
=
childPageIds
[
entryCount
];
index
.
getPage
(
child
).
last
(
cursor
);
}
PageBtreeLeaf
getFirstLeaf
()
throws
SQLException
{
PageBtreeLeaf
getFirstLeaf
()
throws
SQLException
{
int
child
=
childPageIds
[
0
];
int
child
=
childPageIds
[
0
];
return
index
.
getPage
(
child
).
getFirstLeaf
();
return
index
.
getPage
(
child
).
getFirstLeaf
();
}
}
PageBtreeLeaf
getLastLeaf
()
throws
SQLException
{
int
child
=
childPageIds
[
entryCount
-
1
];
return
index
.
getPage
(
child
).
getLastLeaf
();
}
boolean
remove
(
SearchRow
row
)
throws
SQLException
{
boolean
remove
(
SearchRow
row
)
throws
SQLException
{
int
at
=
find
(
row
,
false
,
false
);
int
at
=
find
(
row
,
false
,
false
);
// merge is not implemented to allow concurrent usage
// merge is not implemented to allow concurrent usage
...
@@ -353,6 +368,36 @@ class PageBtreeNode extends PageBtree {
...
@@ -353,6 +368,36 @@ class PageBtreeNode extends PageBtree {
cursor
.
setCurrent
(
leaf
,
0
);
cursor
.
setCurrent
(
leaf
,
0
);
}
}
/**
* Set the cursor to the last row of the previous page.
*
* @param cursor the cursor
* @param row the current row
*/
void
previousPage
(
PageBtreeCursor
cursor
,
int
pageId
)
throws
SQLException
{
int
i
;
// TODO maybe keep the index in the child page (transiently)
for
(
i
=
childPageIds
.
length
-
1
;
i
>=
0
;
i
--)
{
if
(
childPageIds
[
i
]
==
pageId
)
{
i
--;
break
;
}
}
if
(
i
<
0
)
{
if
(
parentPageId
==
Page
.
ROOT
)
{
cursor
.
setCurrent
(
null
,
0
);
return
;
}
PageBtreeNode
previous
=
(
PageBtreeNode
)
index
.
getPage
(
parentPageId
);
previous
.
previousPage
(
cursor
,
getPos
());
return
;
}
PageBtree
page
=
index
.
getPage
(
childPageIds
[
i
]);
PageBtreeLeaf
leaf
=
page
.
getLastLeaf
();
cursor
.
setCurrent
(
leaf
,
leaf
.
entryCount
-
1
);
}
public
String
toString
()
{
public
String
toString
()
{
return
"page["
+
getPos
()
+
"] btree node table:"
+
index
.
getId
()
+
" entries:"
+
entryCount
;
return
"page["
+
getPos
()
+
"] btree node table:"
+
index
.
getId
()
+
" entries:"
+
entryCount
;
}
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/index/PageScanIndex.java
浏览文件 @
7c23654a
...
@@ -196,9 +196,6 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
...
@@ -196,9 +196,6 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
public
void
remove
(
Session
session
,
Row
row
)
throws
SQLException
{
public
void
remove
(
Session
session
,
Row
row
)
throws
SQLException
{
if
(
trace
.
isDebugEnabled
())
{
if
(
trace
.
isDebugEnabled
())
{
trace
.
debug
(
"remove "
+
row
.
getPos
());
trace
.
debug
(
"remove "
+
row
.
getPos
());
if
(
table
.
getId
()
==
0
)
{
System
.
out
.
println
(
"table 0 remove"
);
}
}
}
if
(
tableData
.
getContainsLargeObject
())
{
if
(
tableData
.
getContainsLargeObject
())
{
for
(
int
i
=
0
;
i
<
row
.
getColumnCount
();
i
++)
{
for
(
int
i
=
0
;
i
<
row
.
getColumnCount
();
i
++)
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/log/LogSystem.java
浏览文件 @
7c23654a
...
@@ -87,15 +87,9 @@ public class LogSystem {
...
@@ -87,15 +87,9 @@ public class LogSystem {
*/
*/
public
void
setMaxLogSize
(
long
maxSize
)
{
public
void
setMaxLogSize
(
long
maxSize
)
{
this
.
maxLogSize
=
maxSize
;
this
.
maxLogSize
=
maxSize
;
}
if
(
pageStore
!=
null
)
{
pageStore
.
setMaxLogSize
(
maxSize
);
/**
}
* Get the maximum log file size.
*
* @return the maximum size
*/
public
long
getMaxLogSize
()
{
return
maxLogSize
;
}
}
/**
/**
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/message/Message.java
浏览文件 @
7c23654a
...
@@ -286,6 +286,10 @@ public class Message {
...
@@ -286,6 +286,10 @@ public class Message {
*/
*/
public
static
SQLException
convertIOException
(
IOException
e
,
String
message
)
{
public
static
SQLException
convertIOException
(
IOException
e
,
String
message
)
{
if
(
message
==
null
)
{
if
(
message
==
null
)
{
Throwable
t
=
e
.
getCause
();
if
(
t
!=
null
&&
t
instanceof
SQLException
)
{
return
(
SQLException
)
t
;
}
return
getSQLException
(
ErrorCode
.
IO_EXCEPTION_1
,
new
String
[]
{
e
.
toString
()
},
e
);
return
getSQLException
(
ErrorCode
.
IO_EXCEPTION_1
,
new
String
[]
{
e
.
toString
()
},
e
);
}
}
return
getSQLException
(
ErrorCode
.
IO_EXCEPTION_2
,
new
String
[]
{
e
.
toString
(),
message
},
e
);
return
getSQLException
(
ErrorCode
.
IO_EXCEPTION_2
,
new
String
[]
{
e
.
toString
(),
message
},
e
);
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/store/PageLog.java
浏览文件 @
7c23654a
...
@@ -389,18 +389,8 @@ public class PageLog {
...
@@ -389,18 +389,8 @@ public class PageLog {
return
;
return
;
}
}
int
firstDataPageToKeep
=
logIdPageMap
.
get
(
firstUncommittedLog
);
int
firstDataPageToKeep
=
logIdPageMap
.
get
(
firstUncommittedLog
);
trace
.
debug
(
"log.removeUntil "
+
firstDataPageToKeep
);
firstTrunkPage
=
pageOut
.
removeUntil
(
firstTrunkPage
,
firstDataPageToKeep
);
while
(
true
)
{
store
.
setLogFirstPage
(
firstTrunkPage
,
firstDataPageToKeep
);
// TODO keep trunk page in the cache
PageStreamTrunk
t
=
new
PageStreamTrunk
(
store
,
firstTrunkPage
);
t
.
read
();
if
(
t
.
contains
(
firstDataPageToKeep
))
{
store
.
setLogFirstPage
(
t
.
getPos
(),
firstDataPageToKeep
);
break
;
}
firstTrunkPage
=
t
.
getNextTrunk
();
t
.
free
();
}
while
(
firstLogId
<
firstUncommittedLog
)
{
while
(
firstLogId
<
firstUncommittedLog
)
{
if
(
firstLogId
>
0
)
{
if
(
firstLogId
>
0
)
{
// there is no entry for log 0
// there is no entry for log 0
...
@@ -473,4 +463,8 @@ public class PageLog {
...
@@ -473,4 +463,8 @@ public class PageLog {
return
state
;
return
state
;
}
}
public
long
getSize
()
{
return
pageOut
.
getSize
();
}
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/store/PageOutputStream.java
浏览文件 @
7c23654a
...
@@ -30,6 +30,7 @@ public class PageOutputStream extends OutputStream {
...
@@ -30,6 +30,7 @@ public class PageOutputStream extends OutputStream {
private
byte
[]
buffer
=
new
byte
[
1
];
private
byte
[]
buffer
=
new
byte
[
1
];
private
boolean
needFlush
;
private
boolean
needFlush
;
private
boolean
writing
;
private
boolean
writing
;
private
int
pages
;
/**
/**
* Create a new page output stream.
* Create a new page output stream.
...
@@ -97,11 +98,13 @@ public class PageOutputStream extends OutputStream {
...
@@ -97,11 +98,13 @@ public class PageOutputStream extends OutputStream {
}
}
trunkNext
=
reservedPages
.
get
(
len
);
trunkNext
=
reservedPages
.
get
(
len
);
trunk
=
new
PageStreamTrunk
(
store
,
parent
,
trunkPageId
,
trunkNext
,
pageIds
);
trunk
=
new
PageStreamTrunk
(
store
,
parent
,
trunkPageId
,
trunkNext
,
pageIds
);
pages
++;
trunk
.
write
(
null
);
trunk
.
write
(
null
);
reservedPages
.
removeRange
(
0
,
len
+
1
);
reservedPages
.
removeRange
(
0
,
len
+
1
);
nextData
=
trunk
.
getNextDataPage
();
nextData
=
trunk
.
getNextDataPage
();
}
}
data
=
new
PageStreamData
(
store
,
nextData
,
trunk
.
getPos
());
data
=
new
PageStreamData
(
store
,
nextData
,
trunk
.
getPos
());
pages
++;
data
.
initWrite
();
data
.
initWrite
();
}
}
...
@@ -174,4 +177,29 @@ public class PageOutputStream extends OutputStream {
...
@@ -174,4 +177,29 @@ public class PageOutputStream extends OutputStream {
initNextData
();
initNextData
();
}
}
/**
* Remove all pages until the given data page.
*
* @param firstTrunkPage the first trunk page
* @param firstDataPageToKeep the first data page to keep
* @return the trunk page of the data page to keep
*/
int
removeUntil
(
int
firstTrunkPage
,
int
firstDataPageToKeep
)
throws
SQLException
{
trace
.
debug
(
"log.removeUntil "
+
firstDataPageToKeep
);
while
(
true
)
{
// TODO keep trunk page in the cache
PageStreamTrunk
t
=
new
PageStreamTrunk
(
store
,
firstTrunkPage
);
t
.
read
();
if
(
t
.
contains
(
firstDataPageToKeep
))
{
return
t
.
getPos
();
}
firstTrunkPage
=
t
.
getNextTrunk
();
pages
-=
t
.
free
();
}
}
long
getSize
()
{
return
pages
*
store
.
getPageSize
();
}
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/store/PageStore.java
浏览文件 @
7c23654a
...
@@ -12,6 +12,7 @@ import java.sql.SQLException;
...
@@ -12,6 +12,7 @@ import java.sql.SQLException;
import
java.util.HashMap
;
import
java.util.HashMap
;
import
java.util.zip.CRC32
;
import
java.util.zip.CRC32
;
import
org.h2.constant.ErrorCode
;
import
org.h2.constant.ErrorCode
;
import
org.h2.engine.Constants
;
import
org.h2.engine.Database
;
import
org.h2.engine.Database
;
import
org.h2.engine.Session
;
import
org.h2.engine.Session
;
import
org.h2.index.Cursor
;
import
org.h2.index.Cursor
;
...
@@ -24,6 +25,7 @@ import org.h2.message.Message;
...
@@ -24,6 +25,7 @@ import org.h2.message.Message;
import
org.h2.message.Trace
;
import
org.h2.message.Trace
;
import
org.h2.message.TraceSystem
;
import
org.h2.message.TraceSystem
;
import
org.h2.result.Row
;
import
org.h2.result.Row
;
import
org.h2.result.SortOrder
;
import
org.h2.schema.Schema
;
import
org.h2.schema.Schema
;
import
org.h2.table.Column
;
import
org.h2.table.Column
;
import
org.h2.table.IndexColumn
;
import
org.h2.table.IndexColumn
;
...
@@ -36,6 +38,7 @@ import org.h2.util.CacheWriter;
...
@@ -36,6 +38,7 @@ import org.h2.util.CacheWriter;
import
org.h2.util.FileUtils
;
import
org.h2.util.FileUtils
;
import
org.h2.util.New
;
import
org.h2.util.New
;
import
org.h2.util.ObjectArray
;
import
org.h2.util.ObjectArray
;
import
org.h2.util.StatementBuilder
;
import
org.h2.util.StringUtils
;
import
org.h2.util.StringUtils
;
import
org.h2.value.CompareMode
;
import
org.h2.value.CompareMode
;
import
org.h2.value.Value
;
import
org.h2.value.Value
;
...
@@ -66,9 +69,9 @@ import org.h2.value.ValueString;
...
@@ -66,9 +69,9 @@ import org.h2.value.ValueString;
*/
*/
public
class
PageStore
implements
CacheWriter
{
public
class
PageStore
implements
CacheWriter
{
// TODO auto checkpoint
// TODO TestSampleApps
// TODO TestIndex.wideIndex: btree nodes should be full
// TODO check memory usage
// TODO check memory usage
// TODO TestPowerOff
// TODO PageStore.openMetaIndex (desc and nulls first / last)
// TODO PageStore.openMetaIndex (desc and nulls first / last)
// TODO PageBtreeIndex.canGetFirstOrLast
// TODO PageBtreeIndex.canGetFirstOrLast
// TODO btree index with fixed size values doesn't need offset and so on
// TODO btree index with fixed size values doesn't need offset and so on
...
@@ -107,6 +110,7 @@ public class PageStore implements CacheWriter {
...
@@ -107,6 +110,7 @@ public class PageStore implements CacheWriter {
// TODO var int: see google protocol buffers
// TODO var int: see google protocol buffers
// TODO SessionState.logId is no longer needed
// TODO SessionState.logId is no longer needed
// TODO PageData and PageBtree addRowTry: try to simplify
// TODO PageData and PageBtree addRowTry: try to simplify
// TODO performance: maybe don't save direct parent in btree nodes (only root)
// TODO when removing DiskFile:
// TODO when removing DiskFile:
// remove CacheObject.blockCount
// remove CacheObject.blockCount
...
@@ -131,6 +135,8 @@ public class PageStore implements CacheWriter {
...
@@ -131,6 +135,8 @@ public class PageStore implements CacheWriter {
private
static
final
int
PAGE_ID_META_ROOT
=
4
;
private
static
final
int
PAGE_ID_META_ROOT
=
4
;
private
static
final
int
PAGE_ID_LOG_TRUNK
=
5
;
private
static
final
int
PAGE_ID_LOG_TRUNK
=
5
;
private
static
final
int
MIN_PAGE_COUNT
=
6
;
private
static
final
int
INCREMENT_PAGES
=
128
;
private
static
final
int
INCREMENT_PAGES
=
128
;
private
static
final
int
READ_VERSION
=
0
;
private
static
final
int
READ_VERSION
=
0
;
...
@@ -174,6 +180,7 @@ public class PageStore implements CacheWriter {
...
@@ -174,6 +180,7 @@ public class PageStore implements CacheWriter {
private
PageScanIndex
metaIndex
;
private
PageScanIndex
metaIndex
;
private
HashMap
<
Integer
,
Index
>
metaObjects
;
private
HashMap
<
Integer
,
Index
>
metaObjects
;
private
int
systemTableHeadPos
;
private
int
systemTableHeadPos
;
private
long
maxLogSize
=
Constants
.
DEFAULT_MAX_LOG_SIZE
;
/**
/**
* Create a new page store object.
* Create a new page store object.
...
@@ -225,43 +232,14 @@ public class PageStore implements CacheWriter {
...
@@ -225,43 +232,14 @@ public class PageStore implements CacheWriter {
public
void
open
()
throws
SQLException
{
public
void
open
()
throws
SQLException
{
try
{
try
{
if
(
FileUtils
.
exists
(
fileName
))
{
if
(
FileUtils
.
exists
(
fileName
))
{
// existing
if
(
FileUtils
.
length
(
fileName
)
<
MIN_PAGE_COUNT
*
PAGE_SIZE_MIN
)
{
file
=
database
.
openFile
(
fileName
,
accessMode
,
true
);
// the database was not fully created
readStaticHeader
();
openNew
();
freeListPagesPerList
=
PageFreeList
.
getPagesAddressed
(
pageSize
);
}
else
{
fileLength
=
file
.
length
();
openExisting
();
pageCount
=
(
int
)
(
fileLength
/
pageSize
);
if
(
pageCount
<
6
)
{
// not enough pages - must be a new database
// that didn't get created correctly
throw
Message
.
getSQLException
(
ErrorCode
.
FILE_CORRUPTED_1
,
fileName
);
}
readVariableHeader
();
log
=
new
PageLog
(
this
);
log
.
openForReading
(
logFirstTrunkPage
,
logFirstDataPage
);
recover
();
if
(!
database
.
isReadOnly
())
{
recoveryRunning
=
true
;
log
.
free
();
logFirstTrunkPage
=
allocatePage
();
log
.
openForWriting
(
logFirstTrunkPage
);
recoveryRunning
=
false
;
checkpoint
();
}
}
}
else
{
}
else
{
// new
openNew
();
setPageSize
(
PAGE_SIZE_DEFAULT
);
freeListPagesPerList
=
PageFreeList
.
getPagesAddressed
(
pageSize
);
file
=
database
.
openFile
(
fileName
,
accessMode
,
false
);
recoveryRunning
=
true
;
increaseFileSize
(
INCREMENT_PAGES
);
writeStaticHeader
();
log
=
new
PageLog
(
this
);
openMetaIndex
();
logFirstTrunkPage
=
allocatePage
();
log
.
openForWriting
(
logFirstTrunkPage
);
systemTableHeadPos
=
Index
.
EMPTY_HEAD
;
recoveryRunning
=
false
;
}
}
// lastUsedPage = getFreeList().getLastUsed() + 1;
// lastUsedPage = getFreeList().getLastUsed() + 1;
}
catch
(
SQLException
e
)
{
}
catch
(
SQLException
e
)
{
...
@@ -270,6 +248,48 @@ public class PageStore implements CacheWriter {
...
@@ -270,6 +248,48 @@ public class PageStore implements CacheWriter {
}
}
}
}
private
void
openNew
()
throws
SQLException
{
setPageSize
(
PAGE_SIZE_DEFAULT
);
freeListPagesPerList
=
PageFreeList
.
getPagesAddressed
(
pageSize
);
file
=
database
.
openFile
(
fileName
,
accessMode
,
false
);
recoveryRunning
=
true
;
writeStaticHeader
();
writeVariableHeader
();
log
=
new
PageLog
(
this
);
increaseFileSize
(
MIN_PAGE_COUNT
);
openMetaIndex
();
logFirstTrunkPage
=
allocatePage
();
log
.
openForWriting
(
logFirstTrunkPage
);
systemTableHeadPos
=
Index
.
EMPTY_HEAD
;
recoveryRunning
=
false
;
increaseFileSize
(
INCREMENT_PAGES
);
}
private
void
openExisting
()
throws
SQLException
{
file
=
database
.
openFile
(
fileName
,
accessMode
,
true
);
readStaticHeader
();
freeListPagesPerList
=
PageFreeList
.
getPagesAddressed
(
pageSize
);
fileLength
=
file
.
length
();
pageCount
=
(
int
)
(
fileLength
/
pageSize
);
if
(
pageCount
<
MIN_PAGE_COUNT
)
{
close
();
openNew
();
return
;
}
readVariableHeader
();
log
=
new
PageLog
(
this
);
log
.
openForReading
(
logFirstTrunkPage
,
logFirstDataPage
);
recover
();
if
(!
database
.
isReadOnly
())
{
recoveryRunning
=
true
;
log
.
free
();
logFirstTrunkPage
=
allocatePage
();
log
.
openForWriting
(
logFirstTrunkPage
);
recoveryRunning
=
false
;
checkpoint
();
}
}
/**
/**
* Flush all pending changes to disk, and re-open the log file.
* Flush all pending changes to disk, and re-open the log file.
*/
*/
...
@@ -311,19 +331,11 @@ public class PageStore implements CacheWriter {
...
@@ -311,19 +331,11 @@ public class PageStore implements CacheWriter {
}
}
}
}
}
}
try
{
log
.
removeUntil
(
firstUncommittedLog
);
log
.
removeUntil
(
firstUncommittedLog
);
}
catch
(
SQLException
e
)
{
int
test
;
e
.
printStackTrace
();
}
}
}
private
void
readStaticHeader
()
throws
SQLException
{
private
void
readStaticHeader
()
throws
SQLException
{
long
length
=
file
.
length
();
long
length
=
file
.
length
();
if
(
length
<
PAGE_SIZE_MIN
*
2
)
{
throw
Message
.
getSQLException
(
ErrorCode
.
FILE_CORRUPTED_1
,
fileName
);
}
database
.
notifyFileSize
(
length
);
database
.
notifyFileSize
(
length
);
file
.
seek
(
FileStore
.
HEADER_LENGTH
);
file
.
seek
(
FileStore
.
HEADER_LENGTH
);
DataPage
page
=
DataPage
.
create
(
database
,
new
byte
[
PAGE_SIZE_MIN
-
FileStore
.
HEADER_LENGTH
]);
DataPage
page
=
DataPage
.
create
(
database
,
new
byte
[
PAGE_SIZE_MIN
-
FileStore
.
HEADER_LENGTH
]);
...
@@ -335,11 +347,7 @@ public class PageStore implements CacheWriter {
...
@@ -335,11 +347,7 @@ public class PageStore implements CacheWriter {
throw
Message
.
getSQLException
(
ErrorCode
.
FILE_VERSION_ERROR_1
,
fileName
);
throw
Message
.
getSQLException
(
ErrorCode
.
FILE_VERSION_ERROR_1
,
fileName
);
}
}
if
(
writeVersion
!=
0
)
{
if
(
writeVersion
!=
0
)
{
try
{
close
();
file
.
close
();
}
catch
(
IOException
e
)
{
throw
Message
.
convertIOException
(
e
,
"close"
);
}
accessMode
=
"r"
;
accessMode
=
"r"
;
file
=
database
.
openFile
(
fileName
,
accessMode
,
true
);
file
=
database
.
openFile
(
fileName
,
accessMode
,
true
);
}
}
...
@@ -372,7 +380,7 @@ public class PageStore implements CacheWriter {
...
@@ -372,7 +380,7 @@ public class PageStore implements CacheWriter {
*
*
* @param size the page size
* @param size the page size
*/
*/
p
ublic
void
setPageSize
(
int
size
)
throws
SQLException
{
p
rivate
void
setPageSize
(
int
size
)
throws
SQLException
{
if
(
size
<
PAGE_SIZE_MIN
||
size
>
PAGE_SIZE_MAX
)
{
if
(
size
<
PAGE_SIZE_MIN
||
size
>
PAGE_SIZE_MAX
)
{
throw
Message
.
getSQLException
(
ErrorCode
.
FILE_CORRUPTED_1
,
fileName
);
throw
Message
.
getSQLException
(
ErrorCode
.
FILE_CORRUPTED_1
,
fileName
);
}
}
...
@@ -445,7 +453,9 @@ public class PageStore implements CacheWriter {
...
@@ -445,7 +453,9 @@ public class PageStore implements CacheWriter {
public
void
flushLog
()
throws
SQLException
{
public
void
flushLog
()
throws
SQLException
{
if
(
file
!=
null
)
{
if
(
file
!=
null
)
{
log
.
flush
();
synchronized
(
database
)
{
log
.
flush
();
}
}
}
}
}
...
@@ -494,13 +504,7 @@ public class PageStore implements CacheWriter {
...
@@ -494,13 +504,7 @@ public class PageStore implements CacheWriter {
}
}
private
PageFreeList
getFreeList
(
int
i
)
throws
SQLException
{
private
PageFreeList
getFreeList
(
int
i
)
throws
SQLException
{
int
p
;
int
p
=
PAGE_ID_FREE_LIST_ROOT
+
i
*
freeListPagesPerList
;
if
(
i
==
0
)
{
// TODO simplify
p
=
PAGE_ID_FREE_LIST_ROOT
;
}
else
{
p
=
i
*
freeListPagesPerList
;
}
while
(
p
>=
pageCount
)
{
while
(
p
>=
pageCount
)
{
increaseFileSize
(
INCREMENT_PAGES
);
increaseFileSize
(
INCREMENT_PAGES
);
}
}
...
@@ -537,18 +541,20 @@ public class PageStore implements CacheWriter {
...
@@ -537,18 +541,20 @@ public class PageStore implements CacheWriter {
*/
*/
public
int
allocatePage
()
throws
SQLException
{
public
int
allocatePage
()
throws
SQLException
{
int
pos
;
int
pos
;
// TODO could remember the first possible free list page
synchronized
(
database
)
{
for
(
int
i
=
0
;;
i
++)
{
// TODO could remember the first possible free list page
PageFreeList
list
=
getFreeList
(
i
);
for
(
int
i
=
0
;;
i
++)
{
pos
=
list
.
allocate
();
PageFreeList
list
=
getFreeList
(
i
);
if
(
pos
>=
0
)
{
pos
=
list
.
allocate
();
break
;
if
(
pos
>=
0
)
{
break
;
}
}
}
if
(
pos
>=
pageCount
)
{
increaseFileSize
(
INCREMENT_PAGES
);
}
return
pos
;
}
}
if
(
pos
>=
pageCount
)
{
increaseFileSize
(
INCREMENT_PAGES
);
}
return
pos
;
}
}
private
void
increaseFileSize
(
int
increment
)
throws
SQLException
{
private
void
increaseFileSize
(
int
increment
)
throws
SQLException
{
...
@@ -569,17 +575,18 @@ public class PageStore implements CacheWriter {
...
@@ -569,17 +575,18 @@ public class PageStore implements CacheWriter {
if
(
trace
.
isDebugEnabled
())
{
if
(
trace
.
isDebugEnabled
())
{
trace
.
debug
(
"freePage "
+
pageId
);
trace
.
debug
(
"freePage "
+
pageId
);
}
}
cache
.
remove
(
pageId
);
synchronized
(
database
)
{
freePage
(
pageId
);
cache
.
remove
(
pageId
);
if
(
recoveryRunning
)
{
freePage
(
pageId
);
writePage
(
pageId
,
createDataPage
());
if
(
recoveryRunning
)
{
}
else
if
(
logUndo
)
{
writePage
(
pageId
,
createDataPage
());
if
(
old
==
null
)
{
}
else
if
(
logUndo
)
{
old
=
readPage
(
pageId
);
if
(
old
==
null
)
{
old
=
readPage
(
pageId
);
}
log
.
addUndo
(
pageId
,
old
);
}
}
log
.
addUndo
(
pageId
,
old
);
}
}
}
}
/**
/**
...
@@ -598,8 +605,10 @@ public class PageStore implements CacheWriter {
...
@@ -598,8 +605,10 @@ public class PageStore implements CacheWriter {
* @return the record or null
* @return the record or null
*/
*/
public
Record
getRecord
(
int
pos
)
{
public
Record
getRecord
(
int
pos
)
{
CacheObject
obj
=
cache
.
find
(
pos
);
synchronized
(
database
)
{
return
(
Record
)
obj
;
CacheObject
obj
=
cache
.
find
(
pos
);
return
(
Record
)
obj
;
}
}
}
/**
/**
...
@@ -621,11 +630,13 @@ public class PageStore implements CacheWriter {
...
@@ -621,11 +630,13 @@ public class PageStore implements CacheWriter {
* @param page the page
* @param page the page
*/
*/
public
void
readPage
(
int
pos
,
DataPage
page
)
throws
SQLException
{
public
void
readPage
(
int
pos
,
DataPage
page
)
throws
SQLException
{
if
(
pos
>=
pageCount
)
{
synchronized
(
database
)
{
throw
Message
.
getSQLException
(
ErrorCode
.
FILE_CORRUPTED_1
,
pos
+
" of "
+
pageCount
);
if
(
pos
>=
pageCount
)
{
throw
Message
.
getSQLException
(
ErrorCode
.
FILE_CORRUPTED_1
,
pos
+
" of "
+
pageCount
);
}
file
.
seek
(
pos
<<
pageSizeShift
);
file
.
readFully
(
page
.
getBytes
(),
0
,
pageSize
);
}
}
file
.
seek
(
pos
<<
pageSizeShift
);
file
.
readFully
(
page
.
getBytes
(),
0
,
pageSize
);
}
}
/**
/**
...
@@ -653,8 +664,10 @@ public class PageStore implements CacheWriter {
...
@@ -653,8 +664,10 @@ public class PageStore implements CacheWriter {
* @param data the data
* @param data the data
*/
*/
public
void
writePage
(
int
pageId
,
DataPage
data
)
throws
SQLException
{
public
void
writePage
(
int
pageId
,
DataPage
data
)
throws
SQLException
{
file
.
seek
(((
long
)
pageId
)
<<
pageSizeShift
);
synchronized
(
database
)
{
file
.
write
(
data
.
getBytes
(),
0
,
pageSize
);
file
.
seek
(((
long
)
pageId
)
<<
pageSizeShift
);
file
.
write
(
data
.
getBytes
(),
0
,
pageSize
);
}
}
}
/**
/**
...
@@ -663,7 +676,9 @@ public class PageStore implements CacheWriter {
...
@@ -663,7 +676,9 @@ public class PageStore implements CacheWriter {
* @param pageId the page id
* @param pageId the page id
*/
*/
public
void
removeRecord
(
int
pageId
)
{
public
void
removeRecord
(
int
pageId
)
{
cache
.
remove
(
pageId
);
synchronized
(
database
)
{
cache
.
remove
(
pageId
);
}
}
}
Database
getDatabase
()
{
Database
getDatabase
()
{
...
@@ -719,8 +734,10 @@ public class PageStore implements CacheWriter {
...
@@ -719,8 +734,10 @@ public class PageStore implements CacheWriter {
* @param add true if the row is added, false if it is removed
* @param add true if the row is added, false if it is removed
*/
*/
public
void
logAddOrRemoveRow
(
Session
session
,
int
tableId
,
Row
row
,
boolean
add
)
throws
SQLException
{
public
void
logAddOrRemoveRow
(
Session
session
,
int
tableId
,
Row
row
,
boolean
add
)
throws
SQLException
{
if
(!
recoveryRunning
)
{
synchronized
(
database
)
{
log
.
logAddOrRemoveRow
(
session
,
tableId
,
row
,
add
);
if
(!
recoveryRunning
)
{
log
.
logAddOrRemoveRow
(
session
,
tableId
,
row
,
add
);
}
}
}
}
}
...
@@ -730,7 +747,12 @@ public class PageStore implements CacheWriter {
...
@@ -730,7 +747,12 @@ public class PageStore implements CacheWriter {
* @param session the session
* @param session the session
*/
*/
public
void
commit
(
Session
session
)
throws
SQLException
{
public
void
commit
(
Session
session
)
throws
SQLException
{
log
.
commit
(
session
);
synchronized
(
database
)
{
log
.
commit
(
session
);
if
(
log
.
getSize
()
>
maxLogSize
)
{
checkpoint
();
}
}
}
}
/**
/**
...
@@ -835,12 +857,21 @@ public class PageStore implements CacheWriter {
...
@@ -835,12 +857,21 @@ public class PageStore implements CacheWriter {
}
}
TableData
table
=
(
TableData
)
p
.
getTable
();
TableData
table
=
(
TableData
)
p
.
getTable
();
Column
[]
tableCols
=
table
.
getColumns
();
Column
[]
tableCols
=
table
.
getColumns
();
Column
[]
cols
=
new
Column
[
columns
.
length
];
IndexColumn
[]
cols
=
new
Index
Column
[
columns
.
length
];
for
(
int
i
=
0
;
i
<
columns
.
length
;
i
++)
{
for
(
int
i
=
0
;
i
<
columns
.
length
;
i
++)
{
cols
[
i
]
=
tableCols
[
Integer
.
parseInt
(
columns
[
i
])];
String
c
=
columns
[
i
];
IndexColumn
ic
=
new
IndexColumn
();
int
idx
=
c
.
indexOf
(
'/'
);
if
(
idx
>=
0
)
{
String
s
=
c
.
substring
(
idx
+
1
);
ic
.
sortType
=
Integer
.
parseInt
(
s
);
c
=
c
.
substring
(
0
,
idx
);
}
Column
column
=
tableCols
[
Integer
.
parseInt
(
c
)];
ic
.
column
=
column
;
cols
[
i
]
=
ic
;
}
}
IndexColumn
[]
indexColumns
=
IndexColumn
.
wrap
(
cols
);
meta
=
table
.
addIndex
(
session
,
"I"
+
id
,
id
,
cols
,
indexType
,
headPos
,
null
);
meta
=
table
.
addIndex
(
session
,
"I"
+
id
,
id
,
indexColumns
,
indexType
,
headPos
,
null
);
}
}
metaObjects
.
put
(
id
,
meta
);
metaObjects
.
put
(
id
,
meta
);
}
}
...
@@ -853,12 +884,19 @@ public class PageStore implements CacheWriter {
...
@@ -853,12 +884,19 @@ public class PageStore implements CacheWriter {
*/
*/
public
void
addMeta
(
Index
index
,
Session
session
)
throws
SQLException
{
public
void
addMeta
(
Index
index
,
Session
session
)
throws
SQLException
{
int
type
=
index
instanceof
PageScanIndex
?
META_TYPE_SCAN_INDEX
:
META_TYPE_BTREE_INDEX
;
int
type
=
index
instanceof
PageScanIndex
?
META_TYPE_SCAN_INDEX
:
META_TYPE_BTREE_INDEX
;
Column
[]
columns
=
index
.
getColumns
();
IndexColumn
[]
columns
=
index
.
getIndexColumns
();
String
[]
columnIndexes
=
new
String
[
columns
.
length
];
StatementBuilder
buff
=
new
StatementBuilder
();
for
(
int
i
=
0
;
i
<
columns
.
length
;
i
++)
{
for
(
IndexColumn
col
:
columns
)
{
columnIndexes
[
i
]
=
String
.
valueOf
(
columns
[
i
].
getColumnId
());
buff
.
appendExceptFirst
(
","
);
int
id
=
col
.
column
.
getColumnId
();
buff
.
append
(
id
);
int
sortType
=
col
.
sortType
;
if
(
sortType
!=
0
)
{
buff
.
append
(
'/'
);
buff
.
append
(
sortType
);
}
}
}
String
columnList
=
StringUtils
.
arrayCombine
(
columnIndexes
,
','
);
String
columnList
=
buff
.
toString
(
);
Table
table
=
index
.
getTable
();
Table
table
=
index
.
getTable
();
CompareMode
mode
=
table
.
getCompareMode
();
CompareMode
mode
=
table
.
getCompareMode
();
String
options
=
mode
.
getName
()+
","
+
mode
.
getStrength
();
String
options
=
mode
.
getName
()+
","
+
mode
.
getStrength
();
...
@@ -914,4 +952,13 @@ public class PageStore implements CacheWriter {
...
@@ -914,4 +952,13 @@ public class PageStore implements CacheWriter {
}
}
}
}
/**
* Set the maximum log file size in megabytes.
*
* @param maxSize the new maximum log file size
*/
public
void
setMaxLogSize
(
long
maxSize
)
{
this
.
maxLogSize
=
maxSize
;
}
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/store/PageStreamTrunk.java
浏览文件 @
7c23654a
...
@@ -126,16 +126,21 @@ public class PageStreamTrunk extends Record {
...
@@ -126,16 +126,21 @@ public class PageStreamTrunk extends Record {
/**
/**
* Free this page and all data pages.
* Free this page and all data pages.
*
* @return the number of pages freed
*/
*/
void
free
()
throws
SQLException
{
int
free
()
throws
SQLException
{
DataPage
empty
=
store
.
createDataPage
();
DataPage
empty
=
store
.
createDataPage
();
store
.
freePage
(
getPos
(),
false
,
null
);
store
.
freePage
(
getPos
(),
false
,
null
);
int
freed
=
1
;
for
(
int
i
=
0
;
i
<
pageCount
;
i
++)
{
for
(
int
i
=
0
;
i
<
pageCount
;
i
++)
{
int
page
=
pageIds
[
i
];
int
page
=
pageIds
[
i
];
store
.
freePage
(
page
,
false
,
null
);
store
.
freePage
(
page
,
false
,
null
);
freed
++;
store
.
writePage
(
page
,
empty
);
store
.
writePage
(
page
,
empty
);
}
}
store
.
writePage
(
getPos
(),
empty
);
store
.
writePage
(
getPos
(),
empty
);
return
freed
;
}
}
/**
/**
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/TestAll.java
浏览文件 @
7c23654a
...
@@ -290,10 +290,13 @@ java org.h2.test.TestAll timer
...
@@ -290,10 +290,13 @@ java org.h2.test.TestAll timer
// 2009-05-18: 18 tests fail with page store (first loop)
// 2009-05-18: 18 tests fail with page store (first loop)
// 2009-05-30: 15 tests fail with page store (first loop)
// 2009-05-30: 15 tests fail with page store (first loop)
// 2009-06-19: 10 tests fail with page store (first loop)
// 2009-06-19: 10 tests fail with page store (first loop)
// 2009-06-24: 3 tests fail with page store (first loop)
// System.setProperty("h2.pageStore", "true");
// System.setProperty("h2.pageStore", "true");
/*
/*
Console: Start Browser: if ip number changed, try localhost
test case for running out of disk space (using a special file system)
test case for running out of disk space (using a special file system)
auto-build: prepare release
auto-build: prepare release
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/db/TestPowerOff.java
浏览文件 @
7c23654a
...
@@ -13,6 +13,7 @@ import java.sql.SQLException;
...
@@ -13,6 +13,7 @@ import java.sql.SQLException;
import
java.sql.Statement
;
import
java.sql.Statement
;
import
java.util.Random
;
import
java.util.Random
;
import
org.h2.constant.ErrorCode
;
import
org.h2.constant.SysProperties
;
import
org.h2.constant.SysProperties
;
import
org.h2.engine.Constants
;
import
org.h2.engine.Constants
;
import
org.h2.engine.Database
;
import
org.h2.engine.Database
;
...
@@ -289,7 +290,7 @@ public class TestPowerOff extends TestBase {
...
@@ -289,7 +290,7 @@ public class TestPowerOff extends TestBase {
}
}
conn
.
close
();
conn
.
close
();
}
catch
(
SQLException
e
)
{
}
catch
(
SQLException
e
)
{
if
(
e
.
getSQLState
().
equals
(
"
90098"
))
{
if
(
e
.
getSQLState
().
equals
(
"
"
+
ErrorCode
.
SIMULATED_POWER_OFF
))
{
// this is ok
// this is ok
}
else
{
}
else
{
throw
e
;
throw
e
;
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/unit/TestPageStore.java
浏览文件 @
7c23654a
...
@@ -6,13 +6,6 @@
...
@@ -6,13 +6,6 @@
*/
*/
package
org
.
h2
.
test
.
unit
;
package
org
.
h2
.
test
.
unit
;
import
java.io.BufferedInputStream
;
import
java.io.BufferedOutputStream
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.FileOutputStream
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.sql.Connection
;
import
java.sql.Connection
;
import
java.sql.ResultSet
;
import
java.sql.ResultSet
;
import
java.sql.SQLException
;
import
java.sql.SQLException
;
...
@@ -20,37 +13,15 @@ import java.sql.Statement;
...
@@ -20,37 +13,15 @@ import java.sql.Statement;
import
java.util.Random
;
import
java.util.Random
;
import
java.util.Set
;
import
java.util.Set
;
import
java.util.TreeSet
;
import
java.util.TreeSet
;
import
org.h2.constant.SysProperties
;
import
org.h2.engine.ConnectionInfo
;
import
org.h2.engine.ConnectionInfo
;
import
org.h2.engine.Database
;
import
org.h2.engine.Database
;
import
org.h2.index.Cursor
;
import
org.h2.index.Index
;
import
org.h2.index.IndexType
;
import
org.h2.index.PageScanIndex
;
import
org.h2.result.Row
;
import
org.h2.schema.Schema
;
import
org.h2.store.PageInputStream
;
import
org.h2.store.PageOutputStream
;
import
org.h2.store.PageStore
;
import
org.h2.table.Column
;
import
org.h2.table.IndexColumn
;
import
org.h2.table.TableData
;
import
org.h2.test.TestBase
;
import
org.h2.test.TestBase
;
import
org.h2.util.IntArray
;
import
org.h2.util.ObjectArray
;
import
org.h2.value.Value
;
import
org.h2.value.ValueInt
;
/**
/**
* Test the page store.
* Test the page store.
*/
*/
public
class
TestPageStore
extends
TestBase
{
public
class
TestPageStore
extends
TestBase
{
private
Database
db
;
private
Schema
schema
;
private
TableData
table
;
private
Index
index
;
/**
/**
* Run just this test.
* Run just this test.
*
*
...
@@ -63,11 +34,6 @@ public class TestPageStore extends TestBase {
...
@@ -63,11 +34,6 @@ public class TestPageStore extends TestBase {
public
void
test
()
throws
Exception
{
public
void
test
()
throws
Exception
{
testFuzzOperations
();
testFuzzOperations
();
testScanIndex
();
// testBtreeIndex();
// testAllocateFree();
// testStreamFuzz();
// testStreamPerformance(false, 1000);
}
}
private
void
testFuzzOperations
()
throws
SQLException
{
private
void
testFuzzOperations
()
throws
SQLException
{
...
@@ -144,236 +110,4 @@ public class TestPageStore extends TestBase {
...
@@ -144,236 +110,4 @@ public class TestPageStore extends TestBase {
trace
(
" "
+
m
);
trace
(
" "
+
m
);
}
}
private
void
testBtreeIndex
()
throws
SQLException
{
if
(!
SysProperties
.
PAGE_STORE
)
{
return
;
}
deleteDb
(
"pageStore"
);
String
fileName
=
getTestDir
(
"/pageStore"
);
new
File
(
fileName
).
delete
();
File
f
=
new
File
(
fileName
+
".dat"
);
f
.
delete
();
db
=
getDatabase
();
PageStore
store
=
new
PageStore
(
db
,
fileName
,
"rw"
,
8192
);
store
.
setPageSize
(
1024
);
store
.
open
();
openBtreeIndex
();
Row
row
;
for
(
int
i
=
10
;
i
<
100
;
i
+=
10
)
{
row
=
table
.
getTemplateRow
();
row
.
setValue
(
0
,
ValueInt
.
get
(
i
));
row
.
setPos
(
i
);
index
.
add
(
db
.
getSystemSession
(),
row
);
}
row
=
table
.
getTemplateRow
();
row
.
setValue
(
0
,
ValueInt
.
get
(
60
));
row
.
setPos
(
60
);
index
.
remove
(
db
.
getSystemSession
(),
row
);
row
=
table
.
getTemplateRow
();
row
.
setValue
(
0
,
ValueInt
.
get
(
60
));
row
.
setPos
(
60
);
index
.
add
(
db
.
getSystemSession
(),
row
);
store
.
checkpoint
();
store
.
close
();
store
=
new
PageStore
(
db
,
fileName
,
"rw"
,
8192
);
store
.
open
();
openBtreeIndex
();
Cursor
cursor
=
index
.
find
(
db
.
getSystemSession
(),
null
,
null
);
for
(
int
i
=
10
;
i
<
100
;
i
+=
10
)
{
assertTrue
(
cursor
.
next
());
Row
r
=
cursor
.
get
();
assertEquals
(
i
,
r
.
getValue
(
0
).
getInt
());
}
assertFalse
(
cursor
.
next
());
store
.
close
();
db
.
shutdownImmediately
();
}
private
void
testScanIndex
()
throws
SQLException
{
if
(!
SysProperties
.
PAGE_STORE
)
{
return
;
}
deleteDb
(
"pageStore"
);
String
fileName
=
getTestDir
(
"/pageStore"
);
new
File
(
fileName
).
delete
();
File
f
=
new
File
(
fileName
+
".dat"
);
f
.
delete
();
db
=
getDatabase
();
PageStore
store
=
new
PageStore
(
db
,
fileName
,
"rw"
,
8192
);
store
.
setPageSize
(
1024
);
store
.
open
();
openScanIndex
();
Row
row
;
for
(
int
i
=
10
;
i
<
100
;
i
+=
10
)
{
row
=
table
.
getTemplateRow
();
row
.
setValue
(
0
,
ValueInt
.
get
(
i
));
row
.
setPos
(
i
);
index
.
add
(
db
.
getSystemSession
(),
row
);
}
row
=
table
.
getTemplateRow
();
row
.
setValue
(
0
,
ValueInt
.
get
(
60
));
row
.
setPos
(
60
);
index
.
remove
(
db
.
getSystemSession
(),
row
);
row
=
table
.
getTemplateRow
();
row
.
setValue
(
0
,
ValueInt
.
get
(
60
));
row
.
setPos
(
60
);
index
.
add
(
db
.
getSystemSession
(),
row
);
store
.
checkpoint
();
store
.
close
();
store
=
new
PageStore
(
db
,
fileName
,
"rw"
,
8192
);
store
.
open
();
openScanIndex
();
Cursor
cursor
=
index
.
find
(
db
.
getSystemSession
(),
null
,
null
);
for
(
int
i
=
10
;
i
<
100
;
i
+=
10
)
{
assertTrue
(
cursor
.
next
());
Row
r
=
cursor
.
get
();
assertEquals
(
i
,
r
.
getValue
(
0
).
getInt
());
}
assertFalse
(
cursor
.
next
());
store
.
close
();
db
.
shutdownImmediately
();
}
private
Database
getDatabase
()
throws
SQLException
{
String
name
=
getTestDir
(
"/pageStore"
);
ConnectionInfo
ci
=
new
ConnectionInfo
(
name
);
return
new
Database
(
name
,
ci
,
null
);
}
private
void
openScanIndex
()
throws
SQLException
{
ObjectArray
cols
=
ObjectArray
.
newInstance
();
cols
.
add
(
new
Column
(
"ID"
,
Value
.
INT
));
schema
=
new
Schema
(
db
,
0
,
""
,
null
,
true
);
table
=
new
TableData
(
schema
,
"PAGE_INDEX"
,
1
,
cols
,
true
,
true
,
false
,
100
,
null
);
index
=
(
PageScanIndex
)
table
.
getScanIndex
(
db
.
getSystemSession
());
}
private
void
openBtreeIndex
()
throws
SQLException
{
ObjectArray
cols
=
ObjectArray
.
newInstance
();
cols
.
add
(
new
Column
(
"ID"
,
Value
.
INT
));
schema
=
new
Schema
(
db
,
0
,
""
,
null
,
true
);
int
id
=
db
.
allocateObjectId
(
true
,
true
);
table
=
new
TableData
(
schema
,
"BTREE_INDEX"
,
id
,
cols
,
true
,
true
,
false
,
100
,
null
);
id
=
db
.
allocateObjectId
(
true
,
true
);
table
.
addIndex
(
db
.
getSystemSession
(),
"BTREE"
,
id
,
IndexColumn
.
wrap
(
table
.
getColumns
()),
IndexType
.
createNonUnique
(
true
),
Index
.
EMPTY_HEAD
,
""
);
index
=
(
PageScanIndex
)
table
.
getScanIndex
(
db
.
getSystemSession
());
}
private
void
testAllocateFree
()
throws
SQLException
{
String
fileName
=
getTestDir
(
"/pageStore"
);
new
File
(
fileName
).
delete
();
File
f
=
new
File
(
fileName
+
".dat"
);
f
.
delete
();
Database
db
=
getDatabase
();
PageStore
store
=
new
PageStore
(
db
,
fileName
,
"rw"
,
8192
);
store
.
setPageSize
(
1024
);
store
.
open
();
IntArray
list
=
new
IntArray
();
int
size
=
270
;
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
int
id
=
store
.
allocatePage
();
list
.
add
(
id
);
}
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
int
id
=
list
.
get
(
i
);
store
.
freePage
(
id
,
false
,
null
);
}
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
int
id
=
store
.
allocatePage
();
int
expected
=
list
.
get
(
list
.
size
()
-
1
-
i
);
assertEquals
(
expected
,
id
);
}
store
.
close
();
db
.
shutdownImmediately
();
new
File
(
fileName
).
delete
();
f
.
delete
();
}
private
void
testStreamPerformance
(
boolean
file
,
int
count
)
throws
Exception
{
String
fileName
=
getTestDir
(
"/pageStore"
);
new
File
(
fileName
).
delete
();
File
f
=
new
File
(
fileName
+
".dat"
);
f
.
delete
();
Database
db
=
getDatabase
();
PageStore
store
=
new
PageStore
(
db
,
fileName
,
"rw"
,
8192
);
store
.
setPageSize
(
8
*
1024
);
byte
[]
buff
=
new
byte
[
100
];
store
.
open
();
int
head
=
store
.
allocatePage
();
OutputStream
out
;
InputStream
in
;
long
start
=
System
.
currentTimeMillis
();
if
(
file
)
{
out
=
new
BufferedOutputStream
(
new
FileOutputStream
(
f
),
4
*
1024
);
}
else
{
out
=
new
PageOutputStream
(
store
,
0
);
}
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
out
.
write
(
buff
);
}
out
.
close
();
if
(
file
)
{
in
=
new
BufferedInputStream
(
new
FileInputStream
(
f
),
4
*
1024
);
}
else
{
in
=
new
PageInputStream
(
store
,
0
,
0
);
}
while
(
true
)
{
int
len
=
in
.
read
(
buff
);
if
(
len
<
0
)
{
break
;
}
}
in
.
close
();
println
((
file
?
"file"
:
"pageStore"
)
+
" "
+
(
System
.
currentTimeMillis
()
-
start
));
store
.
close
();
db
.
shutdownImmediately
();
new
File
(
fileName
).
delete
();
f
.
delete
();
}
private
void
testStreamFuzz
()
throws
Exception
{
String
name
=
"mem:pageStoreStreams"
;
ConnectionInfo
ci
=
new
ConnectionInfo
(
name
);
Database
db
=
new
Database
(
name
,
ci
,
null
);
String
fileName
=
getTestDir
(
"/pageStoreStreams"
);
new
File
(
fileName
).
delete
();
PageStore
store
=
new
PageStore
(
db
,
fileName
,
"rw"
,
8192
);
store
.
open
();
Random
random
=
new
Random
(
1
);
for
(
int
i
=
0
;
i
<
10000
;
i
+=
1000
)
{
int
len
=
i
==
0
?
0
:
random
.
nextInt
(
i
);
byte
[]
data
=
new
byte
[
len
];
random
.
nextBytes
(
data
);
int
head
=
store
.
allocatePage
();
PageOutputStream
out
=
new
PageOutputStream
(
store
,
0
);
for
(
int
p
=
0
;
p
<
len
;)
{
int
l
=
len
==
0
?
0
:
Math
.
min
(
len
-
p
,
random
.
nextInt
(
len
/
10
));
out
.
write
(
data
,
p
,
l
);
p
+=
l
;
}
out
.
close
();
PageInputStream
in
=
new
PageInputStream
(
store
,
0
,
0
);
byte
[]
data2
=
new
byte
[
len
];
for
(
int
off
=
0
;;)
{
int
l
=
random
.
nextInt
(
1
+
len
/
10
)
+
1
;
l
=
in
.
read
(
data2
,
off
,
l
);
if
(
l
<
0
)
{
break
;
}
off
+=
l
;
}
in
.
close
();
assertEquals
(
data
,
data2
);
}
store
.
close
();
db
.
shutdownImmediately
();
new
File
(
fileName
).
delete
();
}
}
}
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/unit/TestRecovery.java
浏览文件 @
7c23654a
...
@@ -9,6 +9,7 @@ package org.h2.test.unit;
...
@@ -9,6 +9,7 @@ package org.h2.test.unit;
import
java.sql.Connection
;
import
java.sql.Connection
;
import
java.sql.SQLException
;
import
java.sql.SQLException
;
import
java.sql.Statement
;
import
java.sql.Statement
;
import
org.h2.constant.SysProperties
;
import
org.h2.test.TestBase
;
import
org.h2.test.TestBase
;
import
org.h2.tools.DeleteDbFiles
;
import
org.h2.tools.DeleteDbFiles
;
import
org.h2.tools.Recover
;
import
org.h2.tools.Recover
;
...
@@ -43,7 +44,12 @@ public class TestRecovery extends TestBase {
...
@@ -43,7 +44,12 @@ public class TestRecovery extends TestBase {
conn
=
getConnection
(
"recovery"
,
"diff"
,
""
);
conn
=
getConnection
(
"recovery"
,
"diff"
,
""
);
stat
=
conn
.
createStatement
();
stat
=
conn
.
createStatement
();
stat
.
execute
(
"runscript from '"
+
baseDir
+
"/recovery.data.sql'"
);
String
name
=
"recovery.data.sql"
;
if
(
SysProperties
.
PAGE_STORE
)
{
name
=
"recovery.h2.sql"
;
}
stat
.
execute
(
"runscript from '"
+
baseDir
+
"/"
+
name
+
"'"
);
stat
.
execute
(
"select * from test"
);
stat
.
execute
(
"select * from test"
);
conn
.
close
();
conn
.
close
();
}
}
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论