Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
b9a93634
提交
b9a93634
authored
12 年前
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
A persistent multi-version map (work in progress) - open old versions
上级
f0d056d5
隐藏空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
124 行增加
和
28 行删除
+124
-28
TestBtreeMapStore.java
h2/src/test/org/h2/test/store/TestBtreeMapStore.java
+61
-9
BtreeMap.java
h2/src/tools/org/h2/dev/store/btree/BtreeMap.java
+24
-9
BtreeMapStore.java
h2/src/tools/org/h2/dev/store/btree/BtreeMapStore.java
+39
-10
没有找到文件。
h2/src/test/org/h2/test/store/TestBtreeMapStore.java
浏览文件 @
b9a93634
...
...
@@ -43,6 +43,7 @@ public class TestBtreeMapStore extends TestBase {
}
public
void
test
()
{
testVersion
();
testRtreeMany
();
testRtree
();
testRandomRtree
();
...
...
@@ -62,8 +63,59 @@ public class TestBtreeMapStore extends TestBase {
testSimple
();
}
private
void
testVersion
()
{
String
fileName
=
getBaseDir
()
+
"/testVersion.h3"
;
FileUtils
.
delete
(
fileName
);
BtreeMapStore
s
;
s
=
openStore
(
fileName
);
BtreeMap
<
String
,
String
>
m
;
s
=
openStore
(
fileName
);
m
=
s
.
openMap
(
"data"
,
String
.
class
,
String
.
class
);
long
first
=
s
.
getCurrentVersion
();
m
.
put
(
"1"
,
"Hello"
);
m
.
put
(
"2"
,
"World"
);
for
(
int
i
=
10
;
i
<
20
;
i
++)
{
m
.
put
(
""
+
i
,
"data"
);
}
s
.
commit
();
long
old
=
s
.
getCurrentVersion
();
m
.
put
(
"1"
,
"Hallo"
);
m
.
put
(
"2"
,
"Welt"
);
BtreeMap
<
String
,
String
>
mFirst
;
mFirst
=
m
.
openVersion
(
first
);
assertEquals
(
0
,
mFirst
.
size
());
BtreeMap
<
String
,
String
>
mOld
;
assertEquals
(
"Hallo"
,
m
.
get
(
"1"
));
assertEquals
(
"Welt"
,
m
.
get
(
"2"
));
mOld
=
m
.
openVersion
(
old
);
assertEquals
(
"Hello"
,
mOld
.
get
(
"1"
));
assertEquals
(
"World"
,
mOld
.
get
(
"2"
));
assertTrue
(
mOld
.
isReadOnly
());
s
.
getCurrentVersion
();
s
.
setRetainChunk
(
0
);
long
old2
=
s
.
store
();
// TODO keep old version after storing
// assertEquals("Hello", mOld.get("1"));
// assertEquals("World", mOld.get("2"));
m
.
put
(
"1"
,
"Hi"
);
m
.
remove
(
"2"
);
s
.
store
();
s
.
close
();
s
=
openStore
(
fileName
);
m
=
s
.
openMap
(
"data"
,
String
.
class
,
String
.
class
);
assertEquals
(
"Hi"
,
m
.
get
(
"1"
));
assertEquals
(
null
,
m
.
get
(
"2"
));
mOld
=
m
.
openVersion
(
old2
);
assertEquals
(
"Hallo"
,
mOld
.
get
(
"1"
));
assertEquals
(
"Welt"
,
mOld
.
get
(
"2"
));
s
.
close
();
}
private
void
testRtreeMany
()
{
String
fileName
=
getBaseDir
()
+
"/test
Meta
.h3"
;
String
fileName
=
getBaseDir
()
+
"/test
Rtree
.h3"
;
FileUtils
.
delete
(
fileName
);
BtreeMapStore
s
;
s
=
openStore
(
fileName
);
...
...
@@ -126,7 +178,7 @@ public class TestBtreeMapStore extends TestBase {
}
private
void
testRtree
()
{
String
fileName
=
getBaseDir
()
+
"/test
Meta
.h3"
;
String
fileName
=
getBaseDir
()
+
"/test
Rtree
.h3"
;
FileUtils
.
delete
(
fileName
);
BtreeMapStore
s
;
s
=
openStore
(
fileName
);
...
...
@@ -218,7 +270,7 @@ public class TestBtreeMapStore extends TestBase {
}
private
void
testRandomRtree
()
{
String
fileName
=
getBaseDir
()
+
"/testRandom.h3"
;
String
fileName
=
getBaseDir
()
+
"/testR
treeR
andom.h3"
;
FileUtils
.
delete
(
fileName
);
BtreeMapStore
s
=
openStore
(
fileName
);
RtreeMap
<
SpatialKey
,
String
>
m
=
s
.
openMap
(
"data"
,
"r"
,
"s2"
,
""
);
...
...
@@ -260,7 +312,7 @@ public class TestBtreeMapStore extends TestBase {
}
private
void
testCustomMapType
()
{
String
fileName
=
getBaseDir
()
+
"/testM
eta
.h3"
;
String
fileName
=
getBaseDir
()
+
"/testM
apType
.h3"
;
FileUtils
.
delete
(
fileName
);
BtreeMapStore
s
;
s
=
openStore
(
fileName
);
...
...
@@ -274,7 +326,7 @@ public class TestBtreeMapStore extends TestBase {
}
private
void
testTruncateFile
()
{
String
fileName
=
getBaseDir
()
+
"/test
Meta
.h3"
;
String
fileName
=
getBaseDir
()
+
"/test
Truncate
.h3"
;
FileUtils
.
delete
(
fileName
);
BtreeMapStore
s
;
BtreeMap
<
Integer
,
String
>
m
;
...
...
@@ -297,7 +349,7 @@ public class TestBtreeMapStore extends TestBase {
}
private
void
testFastDelete
()
{
String
fileName
=
getBaseDir
()
+
"/test
Meta
.h3"
;
String
fileName
=
getBaseDir
()
+
"/test
FastDelete
.h3"
;
FileUtils
.
delete
(
fileName
);
BtreeMapStore
s
;
BtreeMap
<
Integer
,
String
>
m
;
...
...
@@ -325,7 +377,7 @@ public class TestBtreeMapStore extends TestBase {
}
private
void
testRollbackStored
()
{
String
fileName
=
getBaseDir
()
+
"/test
Meta
.h3"
;
String
fileName
=
getBaseDir
()
+
"/test
Rollback
.h3"
;
FileUtils
.
delete
(
fileName
);
BtreeMap
<
String
,
String
>
meta
;
BtreeMapStore
s
=
openStore
(
fileName
);
...
...
@@ -411,7 +463,7 @@ public class TestBtreeMapStore extends TestBase {
}
private
void
testRollbackInMemory
()
{
String
fileName
=
getBaseDir
()
+
"/test
Meta
.h3"
;
String
fileName
=
getBaseDir
()
+
"/test
Rollback
.h3"
;
FileUtils
.
delete
(
fileName
);
BtreeMapStore
s
=
openStore
(
fileName
);
assertEquals
(
1
,
s
.
getCurrentVersion
());
...
...
@@ -477,7 +529,7 @@ public class TestBtreeMapStore extends TestBase {
}
private
void
testLargeImport
()
{
String
fileName
=
getBaseDir
()
+
"/test
Csv
.h3"
;
String
fileName
=
getBaseDir
()
+
"/test
Import
.h3"
;
int
len
=
1000
;
for
(
int
j
=
0
;
j
<
5
;
j
++)
{
FileUtils
.
delete
(
fileName
);
...
...
This diff is collapsed.
Click to expand it.
h2/src/tools/org/h2/dev/store/btree/BtreeMap.java
浏览文件 @
b9a93634
...
...
@@ -19,20 +19,21 @@ import java.util.TreeMap;
*/
public
class
BtreeMap
<
K
,
V
>
{
protected
final
BtreeMapStore
store
;
protected
Page
root
;
protected
BtreeMapStore
store
;
private
final
int
id
;
private
final
String
name
;
private
final
DataType
keyType
;
private
final
DataType
valueType
;
private
final
long
createVersion
;
/**
* The map of old roots. The key is the new version, the value is the root
* before this version.
*/
private
final
TreeMap
<
Long
,
Page
>
oldRoots
=
new
TreeMap
<
Long
,
Page
>();
private
boolean
closed
;
private
boolean
readOnly
;
protected
BtreeMap
(
BtreeMapStore
store
,
int
id
,
String
name
,
...
...
@@ -301,14 +302,14 @@ public class BtreeMap<K, V> {
}
public
void
close
()
{
closed
=
true
;
readOnly
=
true
;
store
=
null
;
oldRoots
.
clear
();
root
=
null
;
}
public
boolean
isClosed
()
{
return
store
==
null
;
return
closed
;
}
/**
...
...
@@ -357,12 +358,12 @@ public class BtreeMap<K, V> {
Page
c2
=
remove
(
c
,
writeVersion
,
key
);
if
(
c2
==
null
)
{
// this child was deleted
if
(
p
.
getKeyCount
()
==
1
)
{
p
=
p
.
copyOnWrite
(
writeVersion
);
p
.
remove
(
index
);
if
(
p
.
getKeyCount
()
==
0
)
{
removePage
(
p
);
p
=
p
.
getChildPage
(
0
);
}
p
=
p
.
copyOnWrite
(
writeVersion
);
p
.
remove
(
index
);
}
else
if
(
oldSize
!=
c2
.
getTotalSize
())
{
p
=
p
.
copyOnWrite
(
writeVersion
);
p
.
setChild
(
index
,
c2
);
...
...
@@ -527,7 +528,7 @@ public class BtreeMap<K, V> {
}
protected
void
checkOpen
()
{
if
(
store
==
null
)
{
if
(
closed
)
{
throw
new
IllegalStateException
(
"This map is closed"
);
}
}
...
...
@@ -545,7 +546,7 @@ public class BtreeMap<K, V> {
if
(
readOnly
)
{
buff
.
append
(
" readOnly"
);
}
if
(
store
==
null
)
{
if
(
closed
)
{
buff
.
append
(
" closed"
);
}
return
buff
.
toString
();
...
...
@@ -576,4 +577,18 @@ public class BtreeMap<K, V> {
store
.
removePage
(
p
.
getPos
());
}
public
BtreeMap
<
K
,
V
>
openVersion
(
long
version
)
{
if
(
version
<
createVersion
)
{
throw
new
IllegalArgumentException
(
"Unknown version"
);
}
if
(!
oldRoots
.
containsKey
(
version
))
{
return
store
.
openMapVersion
(
version
,
name
);
}
Page
root
=
oldRoots
.
get
(
version
);
BtreeMap
<
K
,
V
>
m
=
new
BtreeMap
<
K
,
V
>(
store
,
id
,
name
,
keyType
,
valueType
,
createVersion
);
m
.
readOnly
=
true
;
m
.
root
=
root
;
return
m
;
}
}
This diff is collapsed.
Click to expand it.
h2/src/tools/org/h2/dev/store/btree/BtreeMapStore.java
浏览文件 @
b9a93634
...
...
@@ -40,7 +40,6 @@ blockSize=4096
TODO:
- ability to diff / merge versions
- map.getVersion and opening old maps read-only
- limited support for writing to old versions (branches)
- implement complete java.util.Map interface
- maybe rename to MVStore, MVMap, TestMVStore
...
...
@@ -58,6 +57,9 @@ TODO:
- support database version / schema version
- implement more counted b-tree (skip, get positions)
- merge pages if small
- r-tree: add missing features (NN search for example)
- compression: maybe hash table reset speeds up compression
- avoid using java.util.Properties (it allocates quite a lot of memory)
*/
...
...
@@ -142,6 +144,24 @@ public class BtreeMapStore {
return
s
;
}
@SuppressWarnings
(
"unchecked"
)
<
T
extends
BtreeMap
<?,
?>>
T
openMapVersion
(
long
version
,
String
name
)
{
// TODO reduce copy & pasted source code
BtreeMap
<
String
,
String
>
oldMeta
=
getMetaMap
(
version
);
String
types
=
oldMeta
.
get
(
"map."
+
name
);
String
[]
idTypeList
=
StringUtils
.
arraySplit
(
types
,
'/'
,
false
);
int
id
=
Integer
.
parseInt
(
idTypeList
[
0
]);
long
createVersion
=
Long
.
parseLong
(
idTypeList
[
1
]);
String
mapType
=
idTypeList
[
2
];
String
keyType
=
idTypeList
[
3
];
String
valueType
=
idTypeList
[
4
];
String
r
=
oldMeta
.
get
(
"root."
+
id
);
long
root
=
r
==
null
?
0
:
Long
.
parseLong
(
r
);
BtreeMap
<?,
?>
m
=
buildMap
(
mapType
,
id
,
name
,
keyType
,
valueType
,
createVersion
);
m
.
setRootPos
(
root
);
return
(
T
)
m
;
}
/**
* Open a map.
*
...
...
@@ -177,19 +197,22 @@ public class BtreeMapStore {
String
r
=
meta
.
get
(
"root."
+
id
);
root
=
r
==
null
?
0
:
Long
.
parseLong
(
r
);
}
DataType
k
=
buildDataType
(
keyType
);
DataType
v
=
buildDataType
(
valueType
);
if
(
mapType
.
equals
(
""
))
{
m
=
new
BtreeMap
<
Object
,
Object
>(
this
,
id
,
name
,
k
,
v
,
createVersion
);
}
else
{
m
=
getMapFactory
().
buildMap
(
mapType
,
this
,
id
,
name
,
k
,
v
,
createVersion
);
}
m
=
buildMap
(
mapType
,
id
,
name
,
keyType
,
valueType
,
createVersion
);
maps
.
put
(
name
,
m
);
m
.
setRootPos
(
root
);
}
return
(
T
)
m
;
}
private
BtreeMap
<?,
?>
buildMap
(
String
mapType
,
int
id
,
String
name
,
String
keyType
,
String
valueType
,
long
createVersion
)
{
DataType
k
=
buildDataType
(
keyType
);
DataType
v
=
buildDataType
(
valueType
);
if
(
mapType
.
equals
(
""
))
{
return
new
BtreeMap
<
Object
,
Object
>(
this
,
id
,
name
,
k
,
v
,
createVersion
);
}
return
getMapFactory
().
buildMap
(
mapType
,
this
,
id
,
name
,
k
,
v
,
createVersion
);
}
/**
* Get the metadata map. It contains the following entries:
*
...
...
@@ -207,6 +230,11 @@ public class BtreeMapStore {
private
BtreeMap
<
String
,
String
>
getMetaMap
(
long
version
)
{
Chunk
c
=
getChunkForVersion
(
version
);
if
(
c
==
null
)
{
throw
new
IllegalArgumentException
(
"Unknown version: "
+
version
);
}
// TODO avoid duplicate code
c
=
readChunkHeader
(
c
.
start
);
BtreeMap
<
String
,
String
>
oldMeta
=
new
BtreeMap
<
String
,
String
>(
this
,
0
,
"old-meta"
,
STRING_TYPE
,
STRING_TYPE
,
0
);
oldMeta
.
setRootPos
(
c
.
metaRootPos
);
return
oldMeta
;
...
...
@@ -603,7 +631,8 @@ public class BtreeMapStore {
*/
long
registerTempPage
(
Page
p
)
{
long
pos
=
--
tempPageId
;
temp
.
put
(
pos
,
p
);
// use -pos so the Long cache can be used
temp
.
put
(-
pos
,
p
);
int
index
=
(
int
)
pos
&
(
tempCache
.
length
-
1
);
tempCache
[
index
]
=
p
;
return
pos
;
...
...
@@ -808,7 +837,7 @@ public class BtreeMapStore {
int
index
=
(
int
)
pos
&
(
tempCache
.
length
-
1
);
Page
p
=
tempCache
[
index
];
if
(
p
==
null
||
p
.
getPos
()
!=
pos
)
{
p
=
temp
.
get
(
pos
);
p
=
temp
.
get
(
-
pos
);
tempCache
[
index
]
=
p
;
}
return
p
;
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论