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