Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
1b19a060
提交
1b19a060
authored
8月 31, 2009
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Page store: refactor to support compacting
上级
c40a4e9a
隐藏空白字符变更
内嵌
并排
正在显示
18 个修改的文件
包含
460 行增加
和
265 行删除
+460
-265
PageBtree.java
h2/src/main/org/h2/index/PageBtree.java
+8
-9
PageBtreeIndex.java
h2/src/main/org/h2/index/PageBtreeIndex.java
+12
-35
PageBtreeLeaf.java
h2/src/main/org/h2/index/PageBtreeLeaf.java
+31
-14
PageBtreeNode.java
h2/src/main/org/h2/index/PageBtreeNode.java
+40
-14
PageData.java
h2/src/main/org/h2/index/PageData.java
+8
-9
PageDataLeaf.java
h2/src/main/org/h2/index/PageDataLeaf.java
+28
-12
PageDataNode.java
h2/src/main/org/h2/index/PageDataNode.java
+39
-13
PageDataOverflow.java
h2/src/main/org/h2/index/PageDataOverflow.java
+34
-11
PageScanIndex.java
h2/src/main/org/h2/index/PageScanIndex.java
+20
-48
Page.java
h2/src/main/org/h2/store/Page.java
+3
-7
PageFreeList.java
h2/src/main/org/h2/store/PageFreeList.java
+31
-10
PageInputStream.java
h2/src/main/org/h2/store/PageInputStream.java
+16
-7
PageLog.java
h2/src/main/org/h2/store/PageLog.java
+5
-9
PageOutputStream.java
h2/src/main/org/h2/store/PageOutputStream.java
+2
-2
PageStore.java
h2/src/main/org/h2/store/PageStore.java
+100
-31
PageStreamData.java
h2/src/main/org/h2/store/PageStreamData.java
+40
-13
PageStreamTrunk.java
h2/src/main/org/h2/store/PageStreamTrunk.java
+42
-20
Recover.java
h2/src/main/org/h2/tools/Recover.java
+1
-1
没有找到文件。
h2/src/main/org/h2/index/PageBtree.java
浏览文件 @
1b19a060
...
...
@@ -9,12 +9,17 @@ package org.h2.index;
import
java.sql.SQLException
;
import
org.h2.result.SearchRow
;
import
org.h2.store.Data
;
import
org.h2.store.
Record
;
import
org.h2.store.
Page
;
/**
* A page that contains index data.
*/
abstract
class
PageBtree
extends
Record
{
public
abstract
class
PageBtree
extends
Page
{
/**
* This is a root page.
*/
static
final
int
ROOT
=
0
;
/**
* Indicator that the row count is not known.
...
...
@@ -66,9 +71,8 @@ abstract class PageBtree extends Record {
*/
protected
boolean
written
;
PageBtree
(
PageBtreeIndex
index
,
int
pageId
,
int
parentPageId
,
Data
data
)
{
PageBtree
(
PageBtreeIndex
index
,
int
pageId
,
Data
data
)
{
this
.
index
=
index
;
this
.
parentPageId
=
parentPageId
;
this
.
data
=
data
;
setPos
(
pageId
);
}
...
...
@@ -129,11 +133,6 @@ abstract class PageBtree extends Record {
return
l
;
}
/**
* Read the data.
*/
abstract
void
read
()
throws
SQLException
;
/**
* 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.
...
...
h2/src/main/org/h2/index/PageBtreeIndex.java
浏览文件 @
1b19a060
...
...
@@ -16,7 +16,6 @@ import org.h2.result.SearchRow;
import
org.h2.store.Data
;
import
org.h2.store.DataPage
;
import
org.h2.store.PageStore
;
import
org.h2.store.Record
;
import
org.h2.table.Column
;
import
org.h2.table.IndexColumn
;
import
org.h2.table.TableData
;
...
...
@@ -46,6 +45,7 @@ public class PageBtreeIndex extends BaseIndex {
throw
Message
.
throwInternalError
(
""
+
indexName
);
}
this
.
store
=
database
.
getPageStore
();
store
.
addIndex
(
this
);
if
(
headPos
==
Index
.
EMPTY_HEAD
)
{
// new index
needRebuild
=
true
;
...
...
@@ -54,7 +54,8 @@ public class PageBtreeIndex extends BaseIndex {
// it should not for new tables, otherwise redo of other operations
// must ensure this page is not used for other things
store
.
addMeta
(
this
,
session
,
headPos
);
PageBtreeLeaf
root
=
new
PageBtreeLeaf
(
this
,
headPos
,
Page
.
ROOT
,
store
.
createData
());
PageBtreeLeaf
root
=
new
PageBtreeLeaf
(
this
,
headPos
,
store
.
createData
());
root
.
parentPageId
=
PageBtree
.
ROOT
;
store
.
updateRecord
(
root
,
true
,
root
.
data
);
}
else
{
this
.
headPos
=
headPos
;
...
...
@@ -101,7 +102,8 @@ public class PageBtreeIndex extends BaseIndex {
page1
.
setPageId
(
id
);
page1
.
setParentPageId
(
headPos
);
page2
.
setParentPageId
(
headPos
);
PageBtreeNode
newRoot
=
new
PageBtreeNode
(
this
,
rootPageId
,
Page
.
ROOT
,
store
.
createData
());
PageBtreeNode
newRoot
=
new
PageBtreeNode
(
this
,
rootPageId
,
store
.
createData
());
newRoot
.
parentPageId
=
PageBtree
.
ROOT
;
newRoot
.
init
(
page1
,
pivot
,
page2
);
store
.
updateRecord
(
page1
,
true
,
page1
.
data
);
store
.
updateRecord
(
page2
,
true
,
page2
.
data
);
...
...
@@ -134,39 +136,13 @@ public class PageBtreeIndex extends BaseIndex {
* @return the page
*/
PageBtree
getPage
(
int
id
)
throws
SQLException
{
Record
rec
=
store
.
getRecord
(
id
);
if
(
rec
!=
null
)
{
if
(
SysProperties
.
CHECK
)
{
if
(!(
rec
instanceof
PageBtree
))
{
throw
Message
.
throwInternalError
(
"Wrong page: "
+
rec
+
" "
+
this
);
}
PageBtree
result
=
(
PageBtree
)
rec
;
if
(
result
.
index
.
headPos
!=
this
.
headPos
)
{
throw
Message
.
throwInternalError
(
"Wrong index: "
+
result
.
index
+
" "
+
this
);
}
}
return
(
PageBtree
)
rec
;
}
Data
data
=
store
.
readPage
(
id
);
data
.
reset
();
int
parentPageId
=
data
.
readInt
();
int
type
=
data
.
readByte
()
&
255
;
PageBtree
result
;
switch
(
type
&
~
Page
.
FLAG_LAST
)
{
case
Page
.
TYPE_BTREE_LEAF
:
result
=
new
PageBtreeLeaf
(
this
,
id
,
parentPageId
,
data
);
break
;
case
Page
.
TYPE_BTREE_NODE
:
result
=
new
PageBtreeNode
(
this
,
id
,
parentPageId
,
data
);
break
;
case
Page
.
TYPE_EMPTY
:
PageBtreeLeaf
empty
=
new
PageBtreeLeaf
(
this
,
id
,
parentPageId
,
data
);
PageBtree
p
=
(
PageBtree
)
store
.
getPage
(
id
);
if
(
p
==
null
)
{
Data
data
=
store
.
createData
();
PageBtreeLeaf
empty
=
new
PageBtreeLeaf
(
this
,
id
,
data
);
return
empty
;
default
:
throw
Message
.
getSQLException
(
ErrorCode
.
FILE_CORRUPTED_1
,
"page="
+
id
+
" type="
+
type
);
}
result
.
read
();
return
result
;
return
p
;
}
public
boolean
canGetFirstOrLast
()
{
...
...
@@ -276,7 +252,8 @@ public class PageBtreeIndex extends BaseIndex {
private
void
removeAllRows
()
throws
SQLException
{
PageBtree
root
=
getPage
(
headPos
);
root
.
freeChildren
();
root
=
new
PageBtreeLeaf
(
this
,
headPos
,
Page
.
ROOT
,
store
.
createData
());
root
=
new
PageBtreeLeaf
(
this
,
headPos
,
store
.
createData
());
root
.
parentPageId
=
PageBtree
.
ROOT
;
store
.
removeRecord
(
headPos
);
store
.
updateRecord
(
root
,
true
,
null
);
rowCount
=
0
;
...
...
h2/src/main/org/h2/index/PageBtreeLeaf.java
浏览文件 @
1b19a060
...
...
@@ -13,37 +13,53 @@ import org.h2.message.Message;
import
org.h2.result.SearchRow
;
import
org.h2.store.Data
;
import
org.h2.store.DataPage
;
import
org.h2.store.Page
;
/**
* A b-tree leaf page that contains index data.
* Format:
* <ul><li>0-3: parent page id (0 for root)
* </li><li>4-4: page type
* </li><li>5-8:
table
id
* </li><li>5-8:
index
id
* </li><li>9-10: entry count
* </li><li>11-: list of key / offset pairs (4 bytes key, 2 bytes offset)
* </li><li>data
* </li></ul>
*/
class
PageBtreeLeaf
extends
PageBtree
{
public
class
PageBtreeLeaf
extends
PageBtree
{
private
static
final
int
OFFSET_LENGTH
=
2
;
private
static
final
int
OFFSET_START
=
11
;
PageBtreeLeaf
(
PageBtreeIndex
index
,
int
pageId
,
int
parentPageId
,
Data
data
)
{
super
(
index
,
pageId
,
parentPageId
,
data
);
PageBtreeLeaf
(
PageBtreeIndex
index
,
int
pageId
,
Data
data
)
{
super
(
index
,
pageId
,
data
);
start
=
OFFSET_START
;
}
void
read
()
throws
SQLException
{
data
.
setPos
(
4
);
/**
* Read a b-tree leaf page.
*
* @param index the index
* @param data the data
* @param pageId the page id
* @return the page
*/
public
static
Page
read
(
PageBtreeIndex
index
,
Data
data
,
int
pageId
)
throws
SQLException
{
PageBtreeLeaf
p
=
new
PageBtreeLeaf
(
index
,
pageId
,
data
);
p
.
read
();
return
p
;
}
private
void
read
()
throws
SQLException
{
data
.
reset
();
this
.
parentPageId
=
data
.
readInt
();
int
type
=
data
.
readByte
();
onlyPosition
=
(
type
&
Page
.
FLAG_LAST
)
==
0
;
int
table
Id
=
data
.
readInt
();
if
(
table
Id
!=
index
.
getId
())
{
int
index
Id
=
data
.
readInt
();
if
(
index
Id
!=
index
.
getId
())
{
throw
Message
.
getSQLException
(
ErrorCode
.
FILE_CORRUPTED_1
,
"page:"
+
getPos
()
+
" expected
table
:"
+
index
.
getId
()
+
"got:"
+
table
Id
);
"page:"
+
getPos
()
+
" expected
index
:"
+
index
.
getId
()
+
"got:"
+
index
Id
);
}
entryCount
=
data
.
readShortInt
();
offsets
=
new
int
[
entryCount
];
...
...
@@ -137,7 +153,8 @@ class PageBtreeLeaf extends PageBtree {
PageBtree
split
(
int
splitPoint
)
throws
SQLException
{
int
newPageId
=
index
.
getPageStore
().
allocatePage
();
PageBtreeLeaf
p2
=
new
PageBtreeLeaf
(
index
,
newPageId
,
parentPageId
,
index
.
getPageStore
().
createData
());
PageBtreeLeaf
p2
=
new
PageBtreeLeaf
(
index
,
newPageId
,
index
.
getPageStore
().
createData
());
p2
.
parentPageId
=
parentPageId
;
for
(
int
i
=
splitPoint
;
i
<
entryCount
;)
{
p2
.
addRowTry
(
getRow
(
splitPoint
));
removeRow
(
splitPoint
);
...
...
@@ -216,7 +233,7 @@ class PageBtreeLeaf extends PageBtree {
void
find
(
PageBtreeCursor
cursor
,
SearchRow
first
,
boolean
bigger
)
throws
SQLException
{
int
i
=
find
(
first
,
bigger
,
false
,
false
);
if
(
i
>
entryCount
)
{
if
(
parentPageId
==
Page
.
ROOT
)
{
if
(
parentPageId
==
Page
Btree
.
ROOT
)
{
return
;
}
PageBtreeNode
next
=
(
PageBtreeNode
)
index
.
getPage
(
parentPageId
);
...
...
@@ -240,7 +257,7 @@ class PageBtreeLeaf extends PageBtree {
* @param cursor the cursor
*/
void
nextPage
(
PageBtreeCursor
cursor
)
throws
SQLException
{
if
(
parentPageId
==
Page
.
ROOT
)
{
if
(
parentPageId
==
Page
Btree
.
ROOT
)
{
cursor
.
setCurrent
(
null
,
0
);
return
;
}
...
...
@@ -254,7 +271,7 @@ class PageBtreeLeaf extends PageBtree {
* @param cursor the cursor
*/
void
previousPage
(
PageBtreeCursor
cursor
)
throws
SQLException
{
if
(
parentPageId
==
Page
.
ROOT
)
{
if
(
parentPageId
==
Page
Btree
.
ROOT
)
{
cursor
.
setCurrent
(
null
,
0
);
return
;
}
...
...
h2/src/main/org/h2/index/PageBtreeNode.java
浏览文件 @
1b19a060
...
...
@@ -7,11 +7,13 @@
package
org
.
h2
.
index
;
import
java.sql.SQLException
;
import
org.h2.constant.ErrorCode
;
import
org.h2.constant.SysProperties
;
import
org.h2.message.Message
;
import
org.h2.result.SearchRow
;
import
org.h2.store.Data
;
import
org.h2.store.DataPage
;
import
org.h2.store.Page
;
import
org.h2.store.PageStore
;
import
org.h2.util.MemoryUtils
;
...
...
@@ -21,18 +23,19 @@ import org.h2.util.MemoryUtils;
* <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>
* <li>5-8: index id</li>
* <li>9-10: entry count</li>
* <li>11-14: row count of all children (-1 if not known)</li>
* <li>15-18: rightmost child page id</li>
* <li>19- 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
{
public
class
PageBtreeNode
extends
PageBtree
{
private
static
final
int
CHILD_OFFSET_PAIR_LENGTH
=
8
;
private
static
final
int
CHILD_OFFSET_PAIR_START
=
1
5
;
private
static
final
int
CHILD_OFFSET_PAIR_START
=
1
9
;
/**
* The page ids of the children.
...
...
@@ -43,15 +46,36 @@ class PageBtreeNode extends PageBtree {
private
int
rowCount
=
UNKNOWN_ROWCOUNT
;
PageBtreeNode
(
PageBtreeIndex
index
,
int
pageId
,
int
parentPageId
,
Data
data
)
{
super
(
index
,
pageId
,
parentPageId
,
data
);
PageBtreeNode
(
PageBtreeIndex
index
,
int
pageId
,
Data
data
)
{
super
(
index
,
pageId
,
data
);
start
=
CHILD_OFFSET_PAIR_START
;
}
void
read
()
{
data
.
setPos
(
4
);
/**
* Read a b-tree node page.
*
* @param index the index
* @param data the data
* @param pageId the page id
* @return the page
*/
public
static
Page
read
(
PageBtreeIndex
index
,
Data
data
,
int
pageId
)
throws
SQLException
{
PageBtreeNode
p
=
new
PageBtreeNode
(
index
,
pageId
,
data
);
p
.
read
();
return
p
;
}
private
void
read
()
throws
SQLException
{
data
.
reset
();
this
.
parentPageId
=
data
.
readInt
();
int
type
=
data
.
readByte
();
onlyPosition
=
(
type
&
Page
.
FLAG_LAST
)
==
0
;
int
indexId
=
data
.
readInt
();
if
(
indexId
!=
index
.
getId
())
{
throw
Message
.
getSQLException
(
ErrorCode
.
FILE_CORRUPTED_1
,
"page:"
+
getPos
()
+
" expected index:"
+
index
.
getId
()
+
"got:"
+
indexId
);
}
entryCount
=
data
.
readShortInt
();
rowCount
=
data
.
readInt
();
if
(!
PageStore
.
STORE_BTREE_ROWCOUNT
)
{
...
...
@@ -176,7 +200,8 @@ class PageBtreeNode extends PageBtree {
PageBtree
split
(
int
splitPoint
)
throws
SQLException
{
int
newPageId
=
index
.
getPageStore
().
allocatePage
();
PageBtreeNode
p2
=
new
PageBtreeNode
(
index
,
newPageId
,
parentPageId
,
index
.
getPageStore
().
createData
());
PageBtreeNode
p2
=
new
PageBtreeNode
(
index
,
newPageId
,
index
.
getPageStore
().
createData
());
p2
.
parentPageId
=
parentPageId
;
if
(
onlyPosition
)
{
// TODO optimize: maybe not required
p2
.
onlyPosition
=
true
;
...
...
@@ -226,7 +251,7 @@ class PageBtreeNode extends PageBtree {
void
find
(
PageBtreeCursor
cursor
,
SearchRow
first
,
boolean
bigger
)
throws
SQLException
{
int
i
=
find
(
first
,
bigger
,
false
,
false
);
if
(
i
>
entryCount
)
{
if
(
parentPageId
==
Page
.
ROOT
)
{
if
(
parentPageId
==
Page
Btree
.
ROOT
)
{
return
;
}
PageBtreeNode
next
=
(
PageBtreeNode
)
index
.
getPage
(
parentPageId
);
...
...
@@ -338,6 +363,7 @@ class PageBtreeNode extends PageBtree {
data
.
reset
();
data
.
writeInt
(
parentPageId
);
data
.
writeByte
((
byte
)
(
Page
.
TYPE_BTREE_NODE
|
(
onlyPosition
?
0
:
Page
.
FLAG_LAST
)));
data
.
writeInt
(
index
.
getId
());
data
.
writeShortInt
(
entryCount
);
data
.
writeInt
(
rowCount
);
data
.
writeInt
(
childPageIds
[
entryCount
]);
...
...
@@ -404,7 +430,7 @@ class PageBtreeNode extends PageBtree {
}
}
if
(
i
>
entryCount
)
{
if
(
parentPageId
==
Page
.
ROOT
)
{
if
(
parentPageId
==
Page
Btree
.
ROOT
)
{
cursor
.
setCurrent
(
null
,
0
);
return
;
}
...
...
@@ -433,7 +459,7 @@ class PageBtreeNode extends PageBtree {
}
}
if
(
i
<
0
)
{
if
(
parentPageId
==
Page
.
ROOT
)
{
if
(
parentPageId
==
Page
Btree
.
ROOT
)
{
cursor
.
setCurrent
(
null
,
0
);
return
;
}
...
...
h2/src/main/org/h2/index/PageData.java
浏览文件 @
1b19a060
...
...
@@ -10,12 +10,17 @@ import java.sql.SQLException;
import
org.h2.engine.Session
;
import
org.h2.result.Row
;
import
org.h2.store.Data
;
import
org.h2.store.
Record
;
import
org.h2.store.
Page
;
/**
* A page that contains data rows.
*/
abstract
class
PageData
extends
Record
{
abstract
class
PageData
extends
Page
{
/**
* This is a root page.
*/
static
final
int
ROOT
=
0
;
/**
* Indicator that the row count is not known.
...
...
@@ -52,9 +57,8 @@ abstract class PageData extends Record {
*/
protected
boolean
written
;
PageData
(
PageScanIndex
index
,
int
pageId
,
int
parentPageId
,
Data
data
)
{
PageData
(
PageScanIndex
index
,
int
pageId
,
Data
data
)
{
this
.
index
=
index
;
this
.
parentPageId
=
parentPageId
;
this
.
data
=
data
;
setPos
(
pageId
);
}
...
...
@@ -95,11 +99,6 @@ abstract class PageData extends Record {
return
l
;
}
/**
* Read the data.
*/
abstract
void
read
()
throws
SQLException
;
/**
* 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.
...
...
h2/src/main/org/h2/index/PageDataLeaf.java
浏览文件 @
1b19a060
...
...
@@ -15,6 +15,7 @@ import org.h2.message.Message;
import
org.h2.result.Row
;
import
org.h2.store.Data
;
import
org.h2.store.DataPage
;
import
org.h2.store.Page
;
import
org.h2.store.PageStore
;
/**
...
...
@@ -29,7 +30,7 @@ import org.h2.store.PageStore;
* </li><li>data
* </li></ul>
*/
class
PageDataLeaf
extends
PageData
{
public
class
PageDataLeaf
extends
PageData
{
private
static
final
int
KEY_OFFSET_PAIR_LENGTH
=
6
;
private
static
final
int
KEY_OFFSET_PAIR_START
=
11
;
...
...
@@ -64,13 +65,28 @@ class PageDataLeaf extends PageData {
*/
private
int
overflowRowSize
;
PageDataLeaf
(
PageScanIndex
index
,
int
pageId
,
int
parentPageId
,
Data
data
)
{
super
(
index
,
pageId
,
parentPageId
,
data
);
PageDataLeaf
(
PageScanIndex
index
,
int
pageId
,
Data
data
)
{
super
(
index
,
pageId
,
data
);
start
=
KEY_OFFSET_PAIR_START
;
}
void
read
()
throws
SQLException
{
data
.
setPos
(
4
);
/**
* Read a data leaf page.
*
* @param index the index
* @param data the data
* @param pageId the page id
* @return the page
*/
public
static
Page
read
(
PageScanIndex
index
,
Data
data
,
int
pageId
)
throws
SQLException
{
PageDataLeaf
p
=
new
PageDataLeaf
(
index
,
pageId
,
data
);
p
.
read
();
return
p
;
}
private
void
read
()
throws
SQLException
{
data
.
reset
();
this
.
parentPageId
=
data
.
readInt
();
int
type
=
data
.
readByte
();
int
tableId
=
data
.
readInt
();
if
(
tableId
!=
index
.
getId
())
{
...
...
@@ -170,7 +186,7 @@ class PageDataLeaf extends PageData {
size
=
pageSize
-
PageDataOverflow
.
START_MORE
;
next
=
index
.
getPageStore
().
allocatePage
();
}
PageDataOverflow
overflow
=
new
PageDataOverflow
(
this
,
page
,
type
,
previous
,
next
,
data
,
dataOffset
,
size
);
PageDataOverflow
overflow
=
new
PageDataOverflow
(
index
,
page
,
type
,
previous
,
next
,
data
,
dataOffset
,
size
);
index
.
getPageStore
().
updateRecord
(
overflow
,
true
,
null
);
dataOffset
+=
size
;
remaining
-=
size
;
...
...
@@ -232,9 +248,8 @@ class PageDataLeaf extends PageData {
int
pageSize
=
store
.
getPageSize
();
data
.
setPos
(
pageSize
);
int
next
=
firstOverflowPageId
;
int
offset
=
pageSize
;
do
{
PageDataOverflow
page
=
index
.
getPageOverflow
(
next
,
this
,
offset
);
PageDataOverflow
page
=
index
.
getPageOverflow
(
next
);
next
=
page
.
readInto
(
data
);
}
while
(
next
!=
0
);
overflowRowSize
=
data
.
length
();
...
...
@@ -257,7 +272,8 @@ class PageDataLeaf extends PageData {
PageData
split
(
int
splitPoint
)
throws
SQLException
{
int
newPageId
=
index
.
getPageStore
().
allocatePage
();
PageDataLeaf
p2
=
new
PageDataLeaf
(
index
,
newPageId
,
parentPageId
,
index
.
getPageStore
().
createData
());
PageDataLeaf
p2
=
new
PageDataLeaf
(
index
,
newPageId
,
index
.
getPageStore
().
createData
());
p2
.
parentPageId
=
parentPageId
;
for
(
int
i
=
splitPoint
;
i
<
entryCount
;)
{
p2
.
addRowTry
(
getRowAt
(
splitPoint
));
removeRow
(
splitPoint
);
...
...
@@ -274,7 +290,7 @@ class PageDataLeaf extends PageData {
}
PageDataLeaf
getNextPage
()
throws
SQLException
{
if
(
parentPageId
==
Page
.
ROOT
)
{
if
(
parentPageId
==
Page
Data
.
ROOT
)
{
return
null
;
}
PageDataNode
next
=
(
PageDataNode
)
index
.
getPage
(
parentPageId
,
-
1
);
...
...
@@ -289,7 +305,7 @@ class PageDataLeaf extends PageData {
if
(
firstOverflowPageId
==
0
)
{
return
;
}
PageDataOverflow
overflow
=
index
.
getPageOverflow
(
firstOverflowPageId
,
this
,
0
);
PageDataOverflow
overflow
=
index
.
getPageOverflow
(
firstOverflowPageId
);
overflow
.
setParent
(
getPos
());
index
.
getPageStore
().
updateRecord
(
overflow
,
true
,
null
);
}
...
...
@@ -312,7 +328,7 @@ class PageDataLeaf extends PageData {
PageStore
store
=
index
.
getPageStore
();
int
next
=
firstOverflowPageId
;
do
{
PageDataOverflow
page
=
index
.
getPageOverflow
(
next
,
this
,
0
);
PageDataOverflow
page
=
index
.
getPageOverflow
(
next
);
store
.
freePage
(
next
,
false
,
null
);
next
=
page
.
getNextOverflow
();
}
while
(
next
!=
0
);
...
...
h2/src/main/org/h2/index/PageDataNode.java
浏览文件 @
1b19a060
...
...
@@ -7,12 +7,13 @@
package
org
.
h2
.
index
;
import
java.sql.SQLException
;
import
org.h2.constant.ErrorCode
;
import
org.h2.engine.Session
;
import
org.h2.message.Message
;
import
org.h2.result.Row
;
import
org.h2.store.Data
;
import
org.h2.store.DataPage
;
import
org.h2.store.Page
;
import
org.h2.util.MemoryUtils
;
/**
...
...
@@ -20,17 +21,18 @@ import org.h2.util.MemoryUtils;
* 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 key
* </li><li>5-8: index id
* </li><li>9-10: entry count
* </li><li>11-14: row count of all children (-1 if not known)
* </li><li>15-18: rightmost child page id
* </li><li>19- 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
{
public
class
PageDataNode
extends
PageData
{
private
static
final
int
ENTRY_START
=
1
5
;
private
static
final
int
ENTRY_START
=
1
9
;
private
static
final
int
ENTRY_LENGTH
=
8
;
...
...
@@ -43,12 +45,34 @@ class PageDataNode extends PageData {
private
int
rowCount
=
UNKNOWN_ROWCOUNT
;
PageDataNode
(
PageScanIndex
index
,
int
pageId
,
int
parentPageId
,
Data
data
)
{
super
(
index
,
pageId
,
parentPageId
,
data
);
PageDataNode
(
PageScanIndex
index
,
int
pageId
,
Data
data
)
{
super
(
index
,
pageId
,
data
);
}
/**
* Read a data node page.
*
* @param index the index
* @param data the data
* @param pageId the page id
* @return the page
*/
public
static
Page
read
(
PageScanIndex
index
,
Data
data
,
int
pageId
)
throws
SQLException
{
PageDataNode
p
=
new
PageDataNode
(
index
,
pageId
,
data
);
p
.
read
();
return
p
;
}
void
read
()
{
data
.
setPos
(
5
);
private
void
read
()
throws
SQLException
{
data
.
reset
();
this
.
parentPageId
=
data
.
readInt
();
data
.
readByte
();
int
indexId
=
data
.
readInt
();
if
(
indexId
!=
index
.
getId
())
{
throw
Message
.
getSQLException
(
ErrorCode
.
FILE_CORRUPTED_1
,
"page:"
+
getPos
()
+
" expected index:"
+
index
.
getId
()
+
"got:"
+
indexId
);
}
entryCount
=
data
.
readShortInt
();
rowCount
=
rowCountStored
=
data
.
readInt
();
childPageIds
=
new
int
[
entryCount
+
1
];
...
...
@@ -122,7 +146,8 @@ class PageDataNode extends PageData {
PageData
split
(
int
splitPoint
)
throws
SQLException
{
int
newPageId
=
index
.
getPageStore
().
allocatePage
();
PageDataNode
p2
=
new
PageDataNode
(
index
,
newPageId
,
parentPageId
,
index
.
getPageStore
().
createData
());
PageDataNode
p2
=
new
PageDataNode
(
index
,
newPageId
,
index
.
getPageStore
().
createData
());
p2
.
parentPageId
=
parentPageId
;
int
firstChild
=
childPageIds
[
splitPoint
];
for
(
int
i
=
splitPoint
;
i
<
entryCount
;)
{
p2
.
addChild
(
p2
.
entryCount
,
childPageIds
[
splitPoint
+
1
],
keys
[
splitPoint
]);
...
...
@@ -171,7 +196,7 @@ class PageDataNode extends PageData {
PageDataLeaf
getNextPage
(
int
key
)
throws
SQLException
{
int
i
=
find
(
key
)
+
1
;
if
(
i
>
entryCount
)
{
if
(
parentPageId
==
Page
.
ROOT
)
{
if
(
parentPageId
==
Page
Data
.
ROOT
)
{
return
null
;
}
PageDataNode
next
=
(
PageDataNode
)
index
.
getPage
(
parentPageId
,
-
1
);
...
...
@@ -271,6 +296,7 @@ class PageDataNode extends PageData {
data
.
reset
();
data
.
writeInt
(
parentPageId
);
data
.
writeByte
((
byte
)
Page
.
TYPE_DATA_NODE
);
data
.
writeInt
(
index
.
getId
());
data
.
writeShortInt
(
entryCount
);
data
.
writeInt
(
rowCountStored
);
data
.
writeInt
(
childPageIds
[
entryCount
]);
...
...
h2/src/main/org/h2/index/PageDataOverflow.java
浏览文件 @
1b19a060
...
...
@@ -11,29 +11,30 @@ import org.h2.constant.ErrorCode;
import
org.h2.message.Message
;
import
org.h2.store.Data
;
import
org.h2.store.DataPage
;
import
org.h2.store.
Record
;
import
org.h2.store.
Page
;
/**
* Overflow data for a leaf page.
* Format:
* <ul><li>0-3: parent page id (0 for root)
* </li><li>4-4: page type
* </li><li>if there is more data: 5-8: next overflow page id
* </li><li>otherwise: 5-6: remaining size
* </li><li>5-8: index id
* </li><li>if there is more data: 9-12: next overflow page id
* </li><li>otherwise: 9-10: remaining size
* </li><li>data
* </li></ul>
*/
public
class
PageDataOverflow
extends
Record
{
public
class
PageDataOverflow
extends
Page
{
/**
* The start of the data in the last overflow page.
*/
static
final
int
START_LAST
=
7
;
static
final
int
START_LAST
=
11
;
/**
* The start of the data in a overflow page that is not the last one.
*/
static
final
int
START_MORE
=
9
;
static
final
int
START_MORE
=
13
;
/**
* The index.
...
...
@@ -62,8 +63,8 @@ public class PageDataOverflow extends Record {
private
Data
data
;
PageDataOverflow
(
Page
DataLeaf
leaf
,
int
pageId
,
int
type
,
int
previous
,
int
next
,
Data
allData
,
int
offset
,
int
size
)
{
this
.
index
=
leaf
.
index
;
PageDataOverflow
(
Page
ScanIndex
index
,
int
pageId
,
int
type
,
int
previous
,
int
next
,
Data
allData
,
int
offset
,
int
size
)
{
this
.
index
=
index
;
setPos
(
pageId
);
this
.
type
=
type
;
this
.
parentPage
=
previous
;
...
...
@@ -72,6 +73,7 @@ public class PageDataOverflow extends Record {
data
=
index
.
getPageStore
().
createData
();
data
.
writeInt
(
parentPage
);
data
.
writeByte
((
byte
)
type
);
data
.
writeInt
(
index
.
getId
());
if
(
type
==
Page
.
TYPE_DATA_OVERFLOW
)
{
data
.
writeInt
(
nextPage
);
}
else
{
...
...
@@ -88,18 +90,39 @@ public class PageDataOverflow extends Record {
* @param data the data page
* @param offset the offset
*/
PageDataOverflow
(
Page
DataLeaf
leaf
,
int
pageId
,
Data
data
,
int
offset
)
{
this
.
index
=
leaf
.
index
;
PageDataOverflow
(
Page
ScanIndex
index
,
int
pageId
,
Data
data
)
{
this
.
index
=
index
;
setPos
(
pageId
);
this
.
data
=
data
;
}
/**
* Read an overflow page.
*
* @param index the index
* @param data the data
* @param pageId the page id
* @return the page
*/
public
static
Page
read
(
PageScanIndex
index
,
Data
data
,
int
pageId
)
throws
SQLException
{
PageDataOverflow
p
=
new
PageDataOverflow
(
index
,
pageId
,
data
);
p
.
read
();
return
p
;
}
/**
* Read the page.
*/
void
read
()
throws
SQLException
{
private
void
read
()
throws
SQLException
{
data
.
reset
();
parentPage
=
data
.
readInt
();
type
=
data
.
readByte
();
int
indexId
=
data
.
readInt
();
if
(
indexId
!=
index
.
getId
())
{
throw
Message
.
getSQLException
(
ErrorCode
.
FILE_CORRUPTED_1
,
"page:"
+
getPos
()
+
" expected index:"
+
index
.
getId
()
+
" got:"
+
indexId
+
" type:"
+
type
);
}
if
(
type
==
(
Page
.
TYPE_DATA_OVERFLOW
|
Page
.
FLAG_LAST
))
{
size
=
data
.
readShortInt
();
nextPage
=
0
;
...
...
h2/src/main/org/h2/index/PageScanIndex.java
浏览文件 @
1b19a060
...
...
@@ -12,8 +12,6 @@ import java.util.HashMap;
import
java.util.HashSet
;
import
java.util.Iterator
;
import
java.util.List
;
import
org.h2.constant.ErrorCode
;
import
org.h2.constant.SysProperties
;
import
org.h2.engine.Constants
;
import
org.h2.engine.Session
;
import
org.h2.log.UndoLogRecord
;
...
...
@@ -22,7 +20,6 @@ import org.h2.result.Row;
import
org.h2.result.SearchRow
;
import
org.h2.store.Data
;
import
org.h2.store.PageStore
;
import
org.h2.store.Record
;
import
org.h2.table.Column
;
import
org.h2.table.IndexColumn
;
import
org.h2.table.TableData
;
...
...
@@ -56,6 +53,7 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
}
tableData
=
table
;
this
.
store
=
database
.
getPageStore
();
store
.
addIndex
(
this
);
if
(!
database
.
isPersistent
())
{
this
.
headPos
=
0
;
throw
Message
.
throwInternalError
(
table
.
getName
());
...
...
@@ -67,7 +65,8 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
// it should not for new tables, otherwise redo of other operations
// must ensure this page is not used for other things
store
.
addMeta
(
this
,
session
,
headPos
);
PageDataLeaf
root
=
new
PageDataLeaf
(
this
,
headPos
,
Page
.
ROOT
,
store
.
createData
());
PageDataLeaf
root
=
new
PageDataLeaf
(
this
,
headPos
,
store
.
createData
());
root
.
parentPageId
=
PageData
.
ROOT
;
store
.
updateRecord
(
root
,
true
,
root
.
data
);
}
else
{
this
.
headPos
=
headPos
;
...
...
@@ -129,7 +128,8 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
page1
.
setPageId
(
id
);
page1
.
setParentPageId
(
headPos
);
page2
.
setParentPageId
(
headPos
);
PageDataNode
newRoot
=
new
PageDataNode
(
this
,
rootPageId
,
Page
.
ROOT
,
store
.
createData
());
PageDataNode
newRoot
=
new
PageDataNode
(
this
,
rootPageId
,
store
.
createData
());
newRoot
.
parentPageId
=
PageData
.
ROOT
;
newRoot
.
init
(
page1
,
pivot
,
page2
);
store
.
updateRecord
(
page1
,
true
,
page1
.
data
);
store
.
updateRecord
(
page2
,
true
,
page2
.
data
);
...
...
@@ -156,20 +156,10 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
* Read an overflow page page.
*
* @param id the page id
* @param leaf the leaf page
* @param offset the offset in bytes
* @return the page
*/
PageDataOverflow
getPageOverflow
(
int
id
,
PageDataLeaf
leaf
,
int
offset
)
throws
SQLException
{
Record
rec
=
store
.
getRecord
(
id
);
if
(
rec
!=
null
)
{
return
(
PageDataOverflow
)
rec
;
}
Data
data
=
store
.
readPage
(
id
);
data
.
reset
();
PageDataOverflow
result
=
new
PageDataOverflow
(
leaf
,
id
,
data
,
offset
);
result
.
read
();
return
result
;
PageDataOverflow
getPageOverflow
(
int
id
)
throws
SQLException
{
return
(
PageDataOverflow
)
store
.
getPage
(
id
);
}
/**
...
...
@@ -180,41 +170,22 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
* @return the page
*/
PageData
getPage
(
int
id
,
int
parent
)
throws
SQLException
{
Record
rec
=
store
.
getRecord
(
id
);
if
(
rec
!=
null
)
{
if
(
SysProperties
.
CHECK
)
{
PageData
result
=
(
PageData
)
rec
;
if
(
result
.
index
.
headPos
!=
headPos
)
{
throw
Message
.
throwInternalError
(
"Wrong index: "
+
result
.
index
.
getName
()
+
":"
+
result
.
index
.
headPos
+
" "
+
getName
()
+
":"
+
headPos
);
}
}
return
(
PageData
)
rec
;
}
Data
data
=
store
.
readPage
(
id
);
data
.
reset
();
int
parentPageId
=
data
.
readInt
();
int
type
=
data
.
readByte
()
&
255
;
PageData
result
;
switch
(
type
&
~
Page
.
FLAG_LAST
)
{
case
Page
.
TYPE_DATA_LEAF
:
result
=
new
PageDataLeaf
(
this
,
id
,
parentPageId
,
data
);
break
;
case
Page
.
TYPE_DATA_NODE
:
result
=
new
PageDataNode
(
this
,
id
,
parentPageId
,
data
);
break
;
case
Page
.
TYPE_EMPTY
:
PageDataLeaf
empty
=
new
PageDataLeaf
(
this
,
id
,
parentPageId
,
data
);
PageData
p
=
(
PageData
)
store
.
getPage
(
id
);
if
(
p
==
null
)
{
Data
data
=
store
.
createData
();
PageDataLeaf
empty
=
new
PageDataLeaf
(
this
,
id
,
data
);
empty
.
parentPageId
=
parent
;
return
empty
;
default
:
throw
Message
.
getSQLException
(
ErrorCode
.
FILE_CORRUPTED_1
,
"page="
+
id
+
" type="
+
type
);
}
result
.
read
();
if
(
p
.
index
.
headPos
!=
headPos
)
{
throw
Message
.
throwInternalError
(
"Wrong index: "
+
p
.
index
.
getName
()
+
":"
+
p
.
index
.
headPos
+
" "
+
getName
()
+
":"
+
headPos
);
}
if
(
parent
!=
-
1
)
{
if
(
result
.
getParentPageId
()
!=
parent
)
{
throw
Message
.
throwInternalError
(
result
+
" parent "
+
result
.
getParentPageId
()
+
" expected "
+
parent
);
if
(
p
.
getParentPageId
()
!=
parent
)
{
throw
Message
.
throwInternalError
(
p
+
" parent "
+
p
.
getParentPageId
()
+
" expected "
+
parent
);
}
}
return
result
;
return
p
;
}
public
boolean
canGetFirstOrLast
()
{
...
...
@@ -308,7 +279,8 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
private
void
removeAllRows
()
throws
SQLException
{
PageData
root
=
getPage
(
headPos
,
0
);
root
.
freeChildren
();
root
=
new
PageDataLeaf
(
this
,
headPos
,
Page
.
ROOT
,
store
.
createData
());
root
=
new
PageDataLeaf
(
this
,
headPos
,
store
.
createData
());
root
.
parentPageId
=
PageData
.
ROOT
;
store
.
removeRecord
(
headPos
);
store
.
updateRecord
(
root
,
true
,
null
);
rowCount
=
0
;
...
...
h2/src/main/org/h2/
index
/Page.java
→
h2/src/main/org/h2/
store
/Page.java
浏览文件 @
1b19a060
...
...
@@ -4,7 +4,8 @@
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
index
;
package
org
.
h2
.
store
;
/**
* A page. Format:
...
...
@@ -13,7 +14,7 @@ package org.h2.index;
* </li><li>page-type specific data
* </li></ul>
*/
public
class
Page
{
public
abstract
class
Page
extends
Record
{
/**
* This is the last page of a chain.
...
...
@@ -65,9 +66,4 @@ public class Page {
*/
public
static
final
int
TYPE_STREAM_DATA
=
8
;
/**
* This is a root page.
*/
static
final
int
ROOT
=
0
;
}
h2/src/main/org/h2/store/PageFreeList.java
浏览文件 @
1b19a060
...
...
@@ -7,7 +7,6 @@ package org.h2.store;
import
java.sql.SQLException
;
import
org.h2.constant.ErrorCode
;
import
org.h2.index.Page
;
import
org.h2.message.Message
;
import
org.h2.util.BitField
;
...
...
@@ -20,7 +19,7 @@ import org.h2.util.BitField;
* <li>5-remainder: data</li>
* </ul>
*/
public
class
PageFreeList
extends
Record
{
public
class
PageFreeList
extends
Page
{
private
static
final
int
DATA_START
=
5
;
...
...
@@ -30,13 +29,39 @@ public class PageFreeList extends Record {
private
boolean
full
;
private
Data
data
;
PageFreeList
(
PageStore
store
,
int
pageId
)
{
private
PageFreeList
(
PageStore
store
,
int
pageId
)
{
setPos
(
pageId
);
this
.
store
=
store
;
pageCount
=
(
store
.
getPageSize
()
-
DATA_START
)
*
8
;
used
.
set
(
0
);
}
/**
* Read a free-list page.
*
* @param store the page store
* @param data the data
* @param pageId the page id
* @return the page
*/
static
PageFreeList
read
(
PageStore
store
,
Data
data
,
int
pageId
)
throws
SQLException
{
PageFreeList
p
=
new
PageFreeList
(
store
,
pageId
);
p
.
data
=
data
;
p
.
read
();
return
p
;
}
/**
* Create a new free-list page.
*
* @param store the page store
* @param pageId the page id
* @return the page
*/
static
PageFreeList
create
(
PageStore
store
,
int
pageId
)
{
return
new
PageFreeList
(
store
,
pageId
);
}
/**
* Allocate a page from the free list.
*
...
...
@@ -114,15 +139,11 @@ public class PageFreeList extends Record {
/**
* Read the page from the disk.
*/
void
read
()
throws
SQLException
{
data
=
store
.
createData
();
store
.
readPage
(
getPos
(),
data
);
private
void
read
()
throws
SQLException
{
data
.
reset
();
int
p
=
data
.
readInt
();
int
t
=
data
.
readByte
();
if
(
t
==
Page
.
TYPE_EMPTY
)
{
return
;
}
if
(
t
!=
Page
.
TYPE_FREE_LIST
||
p
!=
0
)
{
if
(
p
!=
0
)
{
throw
Message
.
getSQLException
(
ErrorCode
.
FILE_CORRUPTED_1
,
"pos:"
+
getPos
()
+
" type:"
+
t
+
" parent:"
+
p
+
" expected type:"
+
Page
.
TYPE_FREE_LIST
);
}
...
...
h2/src/main/org/h2/store/PageInputStream.java
浏览文件 @
1b19a060
...
...
@@ -76,7 +76,7 @@ public class PageInputStream extends InputStream {
}
}
private
void
fillBuffer
()
throws
SQLException
{
private
void
fillBuffer
()
throws
SQLException
,
EOFException
{
if
(
remaining
>
0
||
endOfFile
)
{
return
;
}
...
...
@@ -87,8 +87,11 @@ public class PageInputStream extends InputStream {
int
next
;
while
(
true
)
{
if
(
trunk
==
null
)
{
trunk
=
new
PageStreamTrunk
(
store
,
trunkNext
);
trunk
.
read
();
trunk
=
(
PageStreamTrunk
)
store
.
getPage
(
trunkNext
);
if
(
trunk
==
null
)
{
throw
new
EOFException
();
}
trunk
.
resetIndex
();
trunkNext
=
trunk
.
getNextTrunk
();
}
if
(
trunk
!=
null
)
{
...
...
@@ -104,8 +107,11 @@ public class PageInputStream extends InputStream {
trace
.
debug
(
"pageIn.readPage "
+
next
);
}
dataPage
=
-
1
;
data
=
new
PageStreamData
(
store
,
next
,
0
);
data
.
read
();
data
=
(
PageStreamData
)
store
.
getPage
(
next
);
if
(
data
==
null
)
{
throw
new
EOFException
();
}
data
.
initRead
();
remaining
=
data
.
getLength
();
}
...
...
@@ -120,8 +126,11 @@ public class PageInputStream extends InputStream {
while
(
trunkPage
!=
0
)
{
pages
.
set
(
trunkPage
);
store
.
allocatePage
(
trunkPage
);
PageStreamTrunk
t
=
new
PageStreamTrunk
(
store
,
trunkPage
);
t
.
read
();
PageStreamTrunk
t
=
(
PageStreamTrunk
)
store
.
getPage
(
trunkPage
);
if
(
t
==
null
)
{
break
;
}
t
.
resetIndex
();
while
(
true
)
{
int
n
=
t
.
getNextPageData
();
if
(
n
==
-
1
)
{
...
...
h2/src/main/org/h2/store/PageLog.java
浏览文件 @
1b19a060
...
...
@@ -189,10 +189,8 @@ public class PageLog {
if
(
store
.
getRecord
(
firstTrunkPage
)
!=
null
)
{
throw
Message
.
throwInternalError
(
""
+
store
.
getRecord
(
firstTrunkPage
));
}
PageStreamTrunk
t
=
new
PageStreamTrunk
(
store
,
this
.
firstTrunkPage
);
try
{
t
.
read
();
}
catch
(
SQLException
e
)
{
PageStreamTrunk
t
=
(
PageStreamTrunk
)
store
.
getPage
(
this
.
firstTrunkPage
);
if
(
t
==
null
)
{
store
.
freePage
(
firstTrunkPage
,
false
,
null
);
// EOF
break
;
...
...
@@ -621,9 +619,8 @@ public class PageLog {
private
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
();
PageStreamTrunk
t
=
(
PageStreamTrunk
)
store
.
getPage
(
firstTrunkPage
);
t
.
resetIndex
();
if
(
t
.
contains
(
firstDataPageToKeep
))
{
return
t
.
getPos
();
}
...
...
@@ -725,8 +722,7 @@ public class PageLog {
* @param commit whether the transaction should be committed
*/
void
setInDoubtTransactionState
(
int
sessionId
,
int
pageId
,
boolean
commit
)
throws
SQLException
{
PageStreamData
d
=
new
PageStreamData
(
store
,
pageId
,
0
);
d
.
read
();
PageStreamData
d
=
(
PageStreamData
)
store
.
getPage
(
pageId
);
d
.
initWrite
();
ByteArrayOutputStream
buff
=
new
ByteArrayOutputStream
();
DataOutputStream
o
=
new
DataOutputStream
(
buff
);
...
...
h2/src/main/org/h2/store/PageOutputStream.java
浏览文件 @
1b19a060
...
...
@@ -98,13 +98,13 @@ public class PageOutputStream extends OutputStream {
pageIds
[
i
]
=
reservedPages
.
get
(
i
);
}
trunkNext
=
reservedPages
.
get
(
len
);
trunk
=
new
PageStreamTrunk
(
store
,
parent
,
trunkPageId
,
trunkNext
,
pageIds
);
trunk
=
PageStreamTrunk
.
create
(
store
,
parent
,
trunkPageId
,
trunkNext
,
pageIds
);
pages
++;
trunk
.
write
(
null
);
reservedPages
.
removeRange
(
0
,
len
+
1
);
nextData
=
trunk
.
getNextPageData
();
}
data
=
new
PageStreamData
(
store
,
nextData
,
trunk
.
getPos
());
data
=
PageStreamData
.
create
(
store
,
nextData
,
trunk
.
getPos
());
pages
++;
data
.
initWrite
();
}
...
...
h2/src/main/org/h2/store/PageStore.java
浏览文件 @
1b19a060
...
...
@@ -18,8 +18,12 @@ import org.h2.engine.Session;
import
org.h2.index.Cursor
;
import
org.h2.index.Index
;
import
org.h2.index.IndexType
;
import
org.h2.index.Page
;
import
org.h2.index.PageBtreeIndex
;
import
org.h2.index.PageBtreeLeaf
;
import
org.h2.index.PageBtreeNode
;
import
org.h2.index.PageDataLeaf
;
import
org.h2.index.PageDataNode
;
import
org.h2.index.PageDataOverflow
;
import
org.h2.index.PageScanIndex
;
import
org.h2.log.InDoubtTransaction
;
import
org.h2.log.LogSystem
;
...
...
@@ -192,7 +196,7 @@ public class PageStore implements CacheWriter {
private
Schema
metaSchema
;
private
TableData
metaTable
;
private
PageScanIndex
metaIndex
;
private
HashMap
<
Integer
,
Index
>
metaObjects
;
private
HashMap
<
Integer
,
Index
>
metaObjects
=
New
.
hashMap
()
;
/**
* The map of reserved pages, to ensure index head pages
...
...
@@ -360,32 +364,87 @@ public class PageStore implements CacheWriter {
if
(
free
==
-
1
||
free
<
10
)
{
return
;
}
Record
rec
=
getRecord
(
full
);
if
(
rec
==
null
)
{
Page
p
=
getPage
(
full
);
}
}
else
{
Data
page
=
Data
.
create
(
database
,
pageSize
);
readPage
(
full
,
page
);
int
parent
=
page
.
readInt
();
int
type
=
page
.
readByte
();
boolean
last
=
(
type
&
Page
.
FLAG_LAST
)
!=
0
;
type
=
type
&
~
Page
.
FLAG_LAST
;
System
.
out
.
println
(
"last page is "
+
type
+
" parent: "
+
parent
);
switch
(
type
)
{
case
Page
.
TYPE_EMPTY
:
break
;
case
Page
.
TYPE_FREE_LIST
:
break
;
case
Page
.
TYPE_DATA_LEAF
:
break
;
case
Page
.
TYPE_DATA_NODE
:
case
Page
.
TYPE_DATA_OVERFLOW
:
case
Page
.
TYPE_BTREE_LEAF
:
case
Page
.
TYPE_BTREE_NODE
:
case
Page
.
TYPE_STREAM_TRUNK
:
case
Page
.
TYPE_STREAM_DATA
:
/**
* Read a page from the store.
*
* @param pageId the page id
* @return the page
*/
public
Page
getPage
(
int
pageId
)
throws
SQLException
{
Record
rec
=
getRecord
(
pageId
);
if
(
rec
!=
null
)
{
return
(
Page
)
rec
;
}
Data
data
=
Data
.
create
(
database
,
pageSize
);
readPage
(
pageId
,
data
);
data
.
readInt
();
int
type
=
data
.
readByte
();
Page
p
;
switch
(
type
&
~
Page
.
FLAG_LAST
)
{
case
Page
.
TYPE_EMPTY
:
return
null
;
case
Page
.
TYPE_FREE_LIST
:
p
=
PageFreeList
.
read
(
this
,
data
,
pageId
);
break
;
case
Page
.
TYPE_DATA_LEAF
:
{
int
indexId
=
data
.
readInt
();
PageScanIndex
index
=
(
PageScanIndex
)
metaObjects
.
get
(
indexId
);
if
(
index
==
null
)
{
Message
.
throwInternalError
(
"index not found "
+
indexId
);
}
p
=
PageDataLeaf
.
read
(
index
,
data
,
pageId
);
break
;
}
case
Page
.
TYPE_DATA_NODE
:
{
int
indexId
=
data
.
readInt
();
PageScanIndex
index
=
(
PageScanIndex
)
metaObjects
.
get
(
indexId
);
if
(
index
==
null
)
{
Message
.
throwInternalError
(
"index not found "
+
indexId
);
}
p
=
PageDataNode
.
read
(
index
,
data
,
pageId
);
break
;
}
case
Page
.
TYPE_DATA_OVERFLOW
:
{
int
indexId
=
data
.
readInt
();
PageScanIndex
index
=
(
PageScanIndex
)
metaObjects
.
get
(
indexId
);
if
(
index
==
null
)
{
Message
.
throwInternalError
(
"index not found "
+
indexId
);
}
p
=
PageDataOverflow
.
read
(
index
,
data
,
pageId
);
break
;
}
case
Page
.
TYPE_BTREE_LEAF
:
{
int
indexId
=
data
.
readInt
();
PageBtreeIndex
index
=
(
PageBtreeIndex
)
metaObjects
.
get
(
indexId
);
if
(
index
==
null
)
{
Message
.
throwInternalError
(
"index not found "
+
indexId
);
}
p
=
PageBtreeLeaf
.
read
(
index
,
data
,
pageId
);
break
;
}
case
Page
.
TYPE_BTREE_NODE
:
{
int
indexId
=
data
.
readInt
();
PageBtreeIndex
index
=
(
PageBtreeIndex
)
metaObjects
.
get
(
indexId
);
if
(
index
==
null
)
{
Message
.
throwInternalError
(
"index not found "
+
indexId
);
}
p
=
PageBtreeNode
.
read
(
index
,
data
,
pageId
);
break
;
}
case
Page
.
TYPE_STREAM_TRUNK
:
p
=
PageStreamTrunk
.
read
(
this
,
data
,
pageId
);
break
;
case
Page
.
TYPE_STREAM_DATA
:
p
=
PageStreamData
.
read
(
this
,
data
,
pageId
);
break
;
default
:
throw
Message
.
getSQLException
(
ErrorCode
.
FILE_CORRUPTED_1
,
"page="
+
pageId
+
" type="
+
type
);
}
cache
.
put
(
p
);
return
p
;
}
/**
...
...
@@ -608,12 +667,12 @@ public class PageStore implements CacheWriter {
while
(
p
>=
pageCount
)
{
increaseFileSize
(
INCREMENT_PAGES
);
}
PageFreeList
list
=
(
PageFreeList
)
getRecord
(
p
);
PageFreeList
list
=
null
;
if
(
p
<
pageCount
)
{
list
=
(
PageFreeList
)
getPage
(
p
);
}
if
(
list
==
null
)
{
list
=
new
PageFreeList
(
this
,
p
);
if
(
p
<
pageCount
)
{
list
.
read
();
}
list
=
PageFreeList
.
create
(
this
,
p
);
cache
.
put
(
list
);
}
return
list
;
...
...
@@ -987,7 +1046,7 @@ public class PageStore implements CacheWriter {
META_TABLE_ID
,
cols
,
false
,
true
,
true
,
false
,
headPos
,
systemSession
);
metaIndex
=
(
PageScanIndex
)
metaTable
.
getScanIndex
(
systemSession
);
metaObjects
=
New
.
hashMap
();
metaObjects
.
clear
();
metaObjects
.
put
(-
1
,
metaIndex
);
}
...
...
@@ -1076,6 +1135,15 @@ public class PageStore implements CacheWriter {
metaObjects
.
put
(
id
,
meta
);
}
/**
* Add an index to the in-memory index map.
*
* @param index the index
*/
public
void
addIndex
(
Index
index
)
{
metaObjects
.
put
(
index
.
getId
(),
index
);
}
/**
* Add the meta data of an index.
*
...
...
@@ -1124,6 +1192,7 @@ public class PageStore implements CacheWriter {
public
void
removeMeta
(
Index
index
,
Session
session
)
throws
SQLException
{
if
(!
recoveryRunning
)
{
removeMetaIndex
(
index
,
session
);
metaObjects
.
remove
(
index
.
getId
());
}
}
...
...
h2/src/main/org/h2/store/PageStreamData.java
浏览文件 @
1b19a060
...
...
@@ -7,9 +7,6 @@
package
org
.
h2
.
store
;
import
java.sql.SQLException
;
import
org.h2.constant.ErrorCode
;
import
org.h2.index.Page
;
import
org.h2.message.Message
;
/**
* A data page of a stream. The format is:
...
...
@@ -20,7 +17,7 @@ import org.h2.message.Message;
* <li>9-remainder: data</li>
* </ul>
*/
public
class
PageStreamData
extends
Record
{
public
class
PageStreamData
extends
Page
{
private
static
final
int
LENGTH_START
=
5
;
private
static
final
int
DATA_START
=
9
;
...
...
@@ -31,25 +28,47 @@ public class PageStreamData extends Record {
private
int
remaining
;
private
int
length
;
PageStreamData
(
PageStore
store
,
int
pageId
,
int
trunk
)
{
private
PageStreamData
(
PageStore
store
,
int
pageId
,
int
trunk
)
{
setPos
(
pageId
);
this
.
store
=
store
;
this
.
trunk
=
trunk
;
}
/**
* Read a stream data page.
*
* @param store the page store
* @param data the data
* @param pageId the page id
* @return the page
*/
static
PageStreamData
read
(
PageStore
store
,
Data
data
,
int
pageId
)
{
PageStreamData
p
=
new
PageStreamData
(
store
,
pageId
,
0
);
p
.
data
=
data
;
p
.
read
();
return
p
;
}
/**
* Create a new stream trunk page.
*
* @param store the page store
* @param pageId the page id
* @param trunk the trunk page
* @return the page
*/
static
PageStreamData
create
(
PageStore
store
,
int
pageId
,
int
trunk
)
{
return
new
PageStreamData
(
store
,
pageId
,
trunk
);
}
/**
* Read the page from the disk.
*/
void
read
()
throws
SQLException
{
data
=
store
.
createData
();
store
.
readPage
(
getPos
(),
data
);
private
void
read
()
{
data
.
reset
();
trunk
=
data
.
readInt
();
data
.
setPos
(
4
);
int
t
=
data
.
readByte
();
if
(
t
!=
Page
.
TYPE_STREAM_DATA
)
{
throw
Message
.
getSQLException
(
ErrorCode
.
FILE_CORRUPTED_1
,
"pos:"
+
getPos
()
+
" type:"
+
t
+
" expected type:"
+
Page
.
TYPE_STREAM_DATA
);
}
data
.
readByte
();
length
=
data
.
readInt
();
}
...
...
@@ -133,4 +152,12 @@ public class PageStreamData extends Record {
return
store
.
getPageSize
()
>>
2
;
}
/**
* Reset the index.
*/
void
initRead
()
{
data
.
setPos
(
DATA_START
);
remaining
=
length
;
}
}
\ No newline at end of file
h2/src/main/org/h2/store/PageStreamTrunk.java
浏览文件 @
1b19a060
...
...
@@ -7,10 +7,6 @@
package
org
.
h2
.
store
;
import
java.sql.SQLException
;
import
org.h2.constant.ErrorCode
;
import
org.h2.index.Page
;
import
org.h2.message.Message
;
import
org.h2.util.MemoryUtils
;
/**
* A trunk page of a stream. It contains the page numbers of the stream, and
...
...
@@ -23,7 +19,7 @@ import org.h2.util.MemoryUtils;
* <li>13-remainder: page ids</li>
* </ul>
*/
public
class
PageStreamTrunk
extends
Record
{
public
class
PageStreamTrunk
extends
Page
{
private
static
final
int
DATA_START
=
13
;
...
...
@@ -35,7 +31,7 @@ public class PageStreamTrunk extends Record {
private
Data
data
;
private
int
index
;
PageStreamTrunk
(
PageStore
store
,
int
parent
,
int
pageId
,
int
next
,
int
[]
pageIds
)
{
private
PageStreamTrunk
(
PageStore
store
,
int
parent
,
int
pageId
,
int
next
,
int
[]
pageIds
)
{
setPos
(
pageId
);
this
.
parent
=
parent
;
this
.
store
=
store
;
...
...
@@ -44,28 +40,47 @@ public class PageStreamTrunk extends Record {
this
.
pageIds
=
pageIds
;
}
PageStreamTrunk
(
PageStore
store
,
int
pageId
)
{
private
PageStreamTrunk
(
PageStore
store
,
Data
data
,
int
pageId
)
{
setPos
(
pageId
);
this
.
data
=
data
;
this
.
store
=
store
;
}
/**
* Read a stream trunk page.
*
* @param store the page store
* @param data the data
* @param pageId the page id
* @return the page
*/
static
PageStreamTrunk
read
(
PageStore
store
,
Data
data
,
int
pageId
)
{
PageStreamTrunk
p
=
new
PageStreamTrunk
(
store
,
data
,
pageId
);
p
.
read
();
return
p
;
}
/**
* Create a new stream trunk page.
*
* @param store the page store
* @param parent the parent page
* @param pageId the page id
* @param next the next trunk page
* @param pageIds the stream data page ids
* @return the page
*/
static
PageStreamTrunk
create
(
PageStore
store
,
int
parent
,
int
pageId
,
int
next
,
int
[]
pageIds
)
{
return
new
PageStreamTrunk
(
store
,
parent
,
pageId
,
next
,
pageIds
);
}
/**
* Read the page from the disk.
*/
void
read
()
throws
SQLException
{
data
=
store
.
createData
();
store
.
readPage
(
getPos
(),
data
);
private
void
read
()
{
data
.
reset
();
parent
=
data
.
readInt
();
int
t
=
data
.
readByte
();
if
(
t
==
Page
.
TYPE_EMPTY
)
{
// end of file
pageIds
=
MemoryUtils
.
EMPTY_INTS
;
return
;
}
if
(
t
!=
Page
.
TYPE_STREAM_TRUNK
)
{
throw
Message
.
getSQLException
(
ErrorCode
.
FILE_CORRUPTED_1
,
"pos:"
+
getPos
()
+
" type:"
+
t
+
" parent:"
+
parent
+
" expected type:"
+
Page
.
TYPE_STREAM_TRUNK
);
}
data
.
readByte
();
nextTrunk
=
data
.
readInt
();
pageCount
=
data
.
readInt
();
pageIds
=
new
int
[
pageCount
];
...
...
@@ -74,6 +89,13 @@ public class PageStreamTrunk extends Record {
}
}
/**
* Reset the read/write index.
*/
void
resetIndex
()
{
index
=
0
;
}
void
setNextDataPage
(
int
page
)
{
pageIds
[
index
++]
=
page
;
}
...
...
h2/src/main/org/h2/tools/Recover.java
浏览文件 @
1b19a060
...
...
@@ -27,7 +27,6 @@ import org.h2.command.Parser;
import
org.h2.engine.Constants
;
import
org.h2.engine.DbObject
;
import
org.h2.engine.MetaRecord
;
import
org.h2.index.Page
;
import
org.h2.log.LogFile
;
import
org.h2.message.Message
;
import
org.h2.message.Trace
;
...
...
@@ -41,6 +40,7 @@ import org.h2.store.DiskFile;
import
org.h2.store.FileLister
;
import
org.h2.store.FileStore
;
import
org.h2.store.FileStoreInputStream
;
import
org.h2.store.Page
;
import
org.h2.store.PageFreeList
;
import
org.h2.store.PageLog
;
import
org.h2.store.PageStore
;
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论