Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
d287dfba
提交
d287dfba
authored
16 年前
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
New experimental page store.
上级
a18e7177
显示空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
155 行增加
和
51 行删除
+155
-51
PageFreeList.java
h2/src/main/org/h2/store/PageFreeList.java
+60
-31
PageStore.java
h2/src/main/org/h2/store/PageStore.java
+47
-11
TestAll.java
h2/src/test/org/h2/test/TestAll.java
+1
-0
TestPageStore.java
h2/src/test/org/h2/test/unit/TestPageStore.java
+47
-9
没有找到文件。
h2/src/main/org/h2/store/PageFreeList.java
浏览文件 @
d287dfba
...
...
@@ -15,58 +15,56 @@ import org.h2.util.IntArray;
/**
* The list of free pages of a page store.
* The format of a free list trunk page is:
* <ul><li>0-3: parent page id (
0 for head
)
* <ul><li>0-3: parent page id (
always 0
)
* </li><li>4-4: page type
* </li><li>5-8: the next page (if there are more) or number of entries
* </li><li>9-remainder: data (4 bytes each entry)
* </li></ul>
*/
public
class
PageFreeList
{
public
class
PageFreeList
extends
Record
{
private
final
PageStore
store
;
private
DataPage
page
;
private
int
pageId
;
private
final
DataPage
page
;
private
final
IntArray
array
=
new
IntArray
()
;
private
int
nextPage
;
private
IntArray
array
=
new
IntArray
();
PageFreeList
(
PageStore
store
,
int
pageId
)
throws
SQLException
{
PageFreeList
(
PageStore
store
,
int
pageId
,
int
nextPage
)
{
setPos
(
pageId
);
this
.
page
=
store
.
createDataPage
();
this
.
store
=
store
;
readTrunk
(
pageId
);
int
maybeWorkLikeAStack
;
int
alsoReturnTrunkPagesOnceTheyAreEmpty
;
this
.
nextPage
=
nextPage
;
}
int
allocate
()
throws
SQLException
{
while
(
true
)
{
int
size
=
array
.
size
();
if
(
size
>
0
)
{
int
x
=
array
.
get
(
size
-
1
);
array
.
remove
(
size
-
1
);
return
x
;
}
if
(
nextPage
==
0
)
{
return
-
1
;
}
readTrunk
(
nextPage
);
}
store
.
updateRecord
(
this
);
// no more free pages in this list:
// set the next page (may be 0, meaning no free pages)
store
.
setFreeListRootPage
(
nextPage
,
true
,
0
);
// and then return the page itself
return
getPos
();
}
private
void
readTrunk
(
int
pageId
)
throws
SQLException
{
if
(
nextPage
==
0
)
{
return
;
private
int
getMaxSize
()
{
return
(
store
.
getPageSize
()
-
9
)
/
DataPage
.
LENGTH_INT
;
}
int
parentPage
=
pageId
;
pageId
=
nextPage
;
store
.
readPage
(
pageId
,
page
);
void
read
()
throws
SQLException
{
store
.
readPage
(
getPos
()
,
page
);
int
p
=
page
.
readInt
();
int
t
=
page
.
readByte
();
boolean
last
=
(
t
&
Page
.
FLAG_LAST
)
!=
0
;
t
&=
~
Page
.
FLAG_LAST
;
if
(
t
!=
Page
.
TYPE_FREE_LIST
||
p
!=
parentPage
)
{
if
(
t
!=
Page
.
TYPE_FREE_LIST
||
p
!=
0
)
{
throw
Message
.
getSQLException
(
ErrorCode
.
FILE_CORRUPTED_1
,
"type:"
+
t
+
" parent:"
+
p
+
" expected type:"
+
Page
.
TYPE_FREE_LIST
+
" expected parent:"
+
parentPage
);
" expected type:"
+
Page
.
TYPE_FREE_LIST
);
}
int
size
;
if
(
last
)
{
...
...
@@ -74,15 +72,46 @@ public class PageFreeList {
size
=
page
.
readInt
();
}
else
{
nextPage
=
page
.
readInt
();
size
=
(
store
.
getPageSize
()
-
page
.
length
())
/
DataPage
.
LENGTH_INT
;
size
=
getMaxSize
()
;
}
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
array
.
add
(
page
.
readInt
());
}
}
void
free
(
int
pageId
)
{
void
free
(
int
pageId
)
throws
SQLException
{
store
.
updateRecord
(
this
);
if
(
array
.
size
()
<
getMaxSize
())
{
array
.
add
(
pageId
);
}
else
{
// this page is full:
// the freed page is the next list
this
.
nextPage
=
pageId
;
// set the next page
store
.
setFreeListRootPage
(
pageId
,
false
,
getPos
());
}
}
public
int
getByteCount
(
DataPage
dummy
)
throws
SQLException
{
return
store
.
getPageSize
();
}
public
void
write
(
DataPage
buff
)
throws
SQLException
{
page
.
reset
();
page
.
writeInt
(
0
);
int
type
=
Page
.
TYPE_FREE_LIST
;
if
(
nextPage
==
0
)
{
type
|=
Page
.
FLAG_LAST
;
}
page
.
writeByte
((
byte
)
type
);
if
(
nextPage
!=
0
)
{
page
.
writeInt
(
nextPage
);
}
else
{
page
.
writeInt
(
array
.
size
());
}
for
(
int
i
=
0
;
i
<
array
.
size
();
i
++)
{
page
.
writeInt
(
array
.
get
(
i
));
}
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/store/PageStore.java
浏览文件 @
d287dfba
...
...
@@ -56,6 +56,10 @@ public class PageStore implements CacheWriter {
private
int
systemRootPageId
;
private
int
freeListRootPageId
;
private
int
freePageCount
;
/**
* Number of pages (including free pages).
*/
private
int
pageCount
;
private
int
writeCount
;
private
long
fileLength
;
...
...
@@ -242,6 +246,9 @@ public class PageStore implements CacheWriter {
*/
public
int
allocatePage
()
throws
SQLException
{
if
(
freePageCount
==
0
)
{
if
(
freeListRootPageId
!=
0
)
{
throw
Message
.
getInternalError
(
"freeListRootPageId:"
+
freeListRootPageId
);
}
if
(
pageCount
*
pageSize
>=
fileLength
)
{
long
newLength
=
(
pageCount
+
INCREMENT_PAGES
)
*
pageSize
;
file
.
setLength
(
newLength
);
...
...
@@ -249,8 +256,38 @@ public class PageStore implements CacheWriter {
}
return
pageCount
++;
}
int
todoReturnAFreePage
;
return
0
;
if
(
freeListRootPageId
==
0
)
{
throw
Message
.
getInternalError
();
}
PageFreeList
free
=
(
PageFreeList
)
cache
.
find
(
freeListRootPageId
);
if
(
free
==
null
)
{
free
=
new
PageFreeList
(
this
,
freeListRootPageId
,
0
);
free
.
read
();
}
int
id
=
free
.
allocate
();
freePageCount
--;
return
id
;
}
/**
* Add a page to the free list.
*
* @param pageId the page id
*/
public
void
freePage
(
int
pageId
)
throws
SQLException
{
freePageCount
++;
PageFreeList
free
;
cache
.
remove
(
pageId
);
if
(
freeListRootPageId
==
0
)
{
setFreeListRootPage
(
pageId
,
false
,
0
);
}
else
{
free
=
(
PageFreeList
)
cache
.
find
(
freeListRootPageId
);
if
(
free
==
null
)
{
free
=
new
PageFreeList
(
this
,
freeListRootPageId
,
0
);
free
.
read
();
}
free
.
free
(
pageId
);
}
}
/**
...
...
@@ -325,15 +362,6 @@ public class PageStore implements CacheWriter {
file
.
write
(
data
.
getBytes
(),
0
,
pageSize
);
}
/**
* Add a page to the free list.
*
* @param pageId the page id
*/
public
void
freePage
(
int
pageId
)
{
int
todo
;
}
/**
* Remove a page from the cache.
*
...
...
@@ -343,4 +371,12 @@ public class PageStore implements CacheWriter {
cache
.
remove
(
pageId
);
}
void
setFreeListRootPage
(
int
pageId
,
boolean
existing
,
int
next
)
throws
SQLException
{
this
.
freeListRootPageId
=
pageId
;
if
(!
existing
)
{
PageFreeList
free
=
new
PageFreeList
(
this
,
pageId
,
next
);
updateRecord
(
free
);
}
}
}
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/TestAll.java
浏览文件 @
d287dfba
...
...
@@ -278,6 +278,7 @@ java org.h2.test.TestAll timer
System
.
setProperty
(
"h2.check2"
,
"true"
);
/*
checksum: no need to checksum all data; every 128th byte is enough; but need position+counter
JCR: for each node type, create a table; one 'dynamic' table with parameter;
option to cache the results
<link rel="icon" type="image/png" href="/path/image.png">
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/unit/TestPageStore
Streams
.java
→
h2/src/test/org/h2/test/unit/TestPageStore.java
浏览文件 @
d287dfba
...
...
@@ -13,6 +13,7 @@ import java.io.FileInputStream;
import
java.io.FileOutputStream
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.sql.SQLException
;
import
java.util.Random
;
import
org.h2.engine.ConnectionInfo
;
import
org.h2.engine.Database
;
...
...
@@ -21,11 +22,12 @@ import org.h2.store.PageInputStream;
import
org.h2.store.PageOutputStream
;
import
org.h2.store.PageStore
;
import
org.h2.test.TestBase
;
import
org.h2.util.IntArray
;
/**
* Test
page store input and output streams
.
* Test
the page store
.
*/
public
class
TestPageStore
Streams
extends
TestBase
{
public
class
TestPageStore
extends
TestBase
{
/**
* Run just this test.
...
...
@@ -37,20 +39,56 @@ public class TestPageStoreStreams extends TestBase {
}
public
void
test
()
throws
Exception
{
testFuzz
();
testPerformance
(
false
,
1000
);
testAllocateFree
();
testStreamFuzz
();
testStreamPerformance
(
false
,
1000
);
// testPerformance(true, 1000000);
// testPerformance(false, 1000000);
}
private
void
testPerformance
(
boolean
file
,
int
count
)
throws
Exception
{
String
name
=
"mem:pageStoreStreams"
;
private
void
testAllocateFree
()
throws
SQLException
{
String
fileName
=
getTestDir
(
"/pageStore"
);
new
File
(
fileName
).
delete
();
File
f
=
new
File
(
fileName
+
".dat"
);
f
.
delete
();
Database
db
=
getDatabase
();
PageStore
store
=
new
PageStore
(
db
,
fileName
,
"rw"
,
8192
);
store
.
setPageSize
(
1024
);
store
.
open
();
IntArray
list
=
new
IntArray
();
int
test
;
int
size
=
270
;
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
int
id
=
store
.
allocatePage
();
list
.
add
(
id
);
}
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
int
id
=
list
.
get
(
i
);
store
.
freePage
(
id
);
}
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
int
id
=
store
.
allocatePage
();
int
expected
=
list
.
get
(
list
.
size
()
-
1
-
i
);
assertEquals
(
expected
,
id
);
}
store
.
close
();
db
.
shutdownImmediately
();
new
File
(
fileName
).
delete
();
f
.
delete
();
}
private
Database
getDatabase
()
throws
SQLException
{
String
name
=
"mem:pageStore"
;
ConnectionInfo
ci
=
new
ConnectionInfo
(
name
);
Database
db
=
new
Database
(
name
,
ci
,
null
);
String
fileName
=
getTestDir
(
"/pageStoreStreams"
);
return
new
Database
(
name
,
ci
,
null
);
}
private
void
testStreamPerformance
(
boolean
file
,
int
count
)
throws
Exception
{
String
fileName
=
getTestDir
(
"/pageStore"
);
new
File
(
fileName
).
delete
();
File
f
=
new
File
(
fileName
+
".dat"
);
f
.
delete
();
Database
db
=
getDatabase
();
PageStore
store
=
new
PageStore
(
db
,
fileName
,
"rw"
,
8192
);
store
.
setPageSize
(
8
*
1024
);
byte
[]
buff
=
new
byte
[
100
];
...
...
@@ -88,7 +126,7 @@ public class TestPageStoreStreams extends TestBase {
f
.
delete
();
}
private
void
testFuzz
()
throws
Exception
{
private
void
test
Stream
Fuzz
()
throws
Exception
{
String
name
=
"mem:pageStoreStreams"
;
ConnectionInfo
ci
=
new
ConnectionInfo
(
name
);
Database
db
=
new
Database
(
name
,
ci
,
null
);
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论