Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
ac599513
提交
ac599513
authored
13 年前
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
A persistent tree map (work in progress).
上级
377e6a96
隐藏空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
82 行增加
和
60 行删除
+82
-60
TestTreeMapStore.java
h2/src/test/org/h2/test/unit/TestTreeMapStore.java
+17
-23
BtreeMap.java
h2/src/tools/org/h2/dev/store/btree/BtreeMap.java
+17
-2
BtreeMapStore.java
h2/src/tools/org/h2/dev/store/btree/BtreeMapStore.java
+15
-10
Page.java
h2/src/tools/org/h2/dev/store/btree/Page.java
+33
-25
没有找到文件。
h2/src/test/org/h2/test/unit/TestTreeMapStore.java
浏览文件 @
ac599513
...
...
@@ -10,8 +10,6 @@ import java.util.Random;
import
java.util.TreeMap
;
import
org.h2.dev.store.btree.BtreeMap
;
import
org.h2.dev.store.btree.BtreeMapStore
;
import
org.h2.dev.store.tree.StoredMap
;
import
org.h2.dev.store.tree.TreeMapStore
;
import
org.h2.jaqu.bytecode.Null
;
import
org.h2.store.fs.FileUtils
;
import
org.h2.test.TestBase
;
...
...
@@ -31,10 +29,7 @@ public class TestTreeMapStore extends TestBase {
}
public
void
test
()
throws
Exception
{
// btree
testBtreeStore
();
// left leaning red-black tree
testDefragment
();
testReuseSpace
();
testRandom
();
...
...
@@ -84,13 +79,12 @@ public class TestTreeMapStore extends TestBase {
FileUtils
.
delete
(
fileName
);
long
initialLength
=
0
;
for
(
int
j
=
0
;
j
<
20
;
j
++)
{
TreeMapStore
s
=
T
reeMapStore
.
open
(
fileName
);
Stored
Map
<
Integer
,
String
>
m
=
s
.
openMap
(
"data"
,
Integer
.
class
,
String
.
class
);
BtreeMapStore
s
=
Bt
reeMapStore
.
open
(
fileName
);
Btree
Map
<
Integer
,
String
>
m
=
s
.
openMap
(
"data"
,
Integer
.
class
,
String
.
class
);
for
(
int
i
=
0
;
i
<
10
;
i
++)
{
m
.
put
(
j
+
i
,
"Hello "
+
j
);
}
s
.
store
();
// s.log(s.toString());
s
.
compact
();
s
.
close
();
long
len
=
FileUtils
.
size
(
fileName
);
...
...
@@ -108,8 +102,8 @@ public class TestTreeMapStore extends TestBase {
FileUtils
.
delete
(
fileName
);
long
initialLength
=
0
;
for
(
int
j
=
0
;
j
<
10
;
j
++)
{
TreeMapStore
s
=
T
reeMapStore
.
open
(
fileName
);
Stored
Map
<
Integer
,
String
>
m
=
s
.
openMap
(
"data"
,
Integer
.
class
,
String
.
class
);
BtreeMapStore
s
=
Bt
reeMapStore
.
open
(
fileName
);
Btree
Map
<
Integer
,
String
>
m
=
s
.
openMap
(
"data"
,
Integer
.
class
,
String
.
class
);
for
(
int
i
=
0
;
i
<
10
;
i
++)
{
m
.
put
(
i
,
"Hello"
);
}
...
...
@@ -131,8 +125,8 @@ public class TestTreeMapStore extends TestBase {
private
void
testRandom
()
{
String
fileName
=
getBaseDir
()
+
"/data.h3"
;
FileUtils
.
delete
(
fileName
);
TreeMapStore
s
=
T
reeMapStore
.
open
(
fileName
);
Stored
Map
<
Integer
,
Integer
>
m
=
s
.
openMap
(
"data"
,
Integer
.
class
,
Integer
.
class
);
BtreeMapStore
s
=
Bt
reeMapStore
.
open
(
fileName
);
Btree
Map
<
Integer
,
Integer
>
m
=
s
.
openMap
(
"data"
,
Integer
.
class
,
Integer
.
class
);
TreeMap
<
Integer
,
Integer
>
map
=
new
TreeMap
<
Integer
,
Integer
>();
Random
r
=
new
Random
(
1
);
for
(
int
i
=
0
;
i
<
100
;
i
++)
{
...
...
@@ -159,14 +153,14 @@ public class TestTreeMapStore extends TestBase {
private
void
testKeyValueClasses
()
{
String
fileName
=
getBaseDir
()
+
"/data.h3"
;
FileUtils
.
delete
(
fileName
);
TreeMapStore
s
=
T
reeMapStore
.
open
(
fileName
);
Stored
Map
<
Integer
,
String
>
is
=
s
.
openMap
(
"intString"
,
Integer
.
class
,
String
.
class
);
BtreeMapStore
s
=
Bt
reeMapStore
.
open
(
fileName
);
Btree
Map
<
Integer
,
String
>
is
=
s
.
openMap
(
"intString"
,
Integer
.
class
,
String
.
class
);
is
.
put
(
1
,
"Hello"
);
Stored
Map
<
Integer
,
Integer
>
ii
=
s
.
openMap
(
"intInt"
,
Integer
.
class
,
Integer
.
class
);
Btree
Map
<
Integer
,
Integer
>
ii
=
s
.
openMap
(
"intInt"
,
Integer
.
class
,
Integer
.
class
);
ii
.
put
(
1
,
10
);
Stored
Map
<
String
,
Integer
>
si
=
s
.
openMap
(
"stringInt"
,
String
.
class
,
Integer
.
class
);
Btree
Map
<
String
,
Integer
>
si
=
s
.
openMap
(
"stringInt"
,
String
.
class
,
Integer
.
class
);
si
.
put
(
"Test"
,
10
);
Stored
Map
<
String
,
String
>
ss
=
s
.
openMap
(
"stringString"
,
String
.
class
,
String
.
class
);
Btree
Map
<
String
,
String
>
ss
=
s
.
openMap
(
"stringString"
,
String
.
class
,
String
.
class
);
ss
.
put
(
"Hello"
,
"World"
);
try
{
s
.
openMap
(
"invalid"
,
Null
.
class
,
Integer
.
class
);
...
...
@@ -181,7 +175,7 @@ public class TestTreeMapStore extends TestBase {
// expected
}
s
.
close
();
s
=
T
reeMapStore
.
open
(
fileName
);
s
=
Bt
reeMapStore
.
open
(
fileName
);
is
=
s
.
openMap
(
"intString"
,
Integer
.
class
,
String
.
class
);
assertEquals
(
"Hello"
,
is
.
get
(
1
));
ii
=
s
.
openMap
(
"intInt"
,
Integer
.
class
,
Integer
.
class
);
...
...
@@ -196,8 +190,8 @@ public class TestTreeMapStore extends TestBase {
private
void
testIterate
()
{
String
fileName
=
getBaseDir
()
+
"/data.h3"
;
FileUtils
.
delete
(
fileName
);
TreeMapStore
s
=
T
reeMapStore
.
open
(
fileName
);
Stored
Map
<
Integer
,
String
>
m
=
s
.
openMap
(
"data"
,
Integer
.
class
,
String
.
class
);
BtreeMapStore
s
=
Bt
reeMapStore
.
open
(
fileName
);
Btree
Map
<
Integer
,
String
>
m
=
s
.
openMap
(
"data"
,
Integer
.
class
,
String
.
class
);
Iterator
<
Integer
>
it
=
m
.
keyIterator
(
null
);
assertFalse
(
it
.
hasNext
());
for
(
int
i
=
0
;
i
<
10
;
i
++)
{
...
...
@@ -229,8 +223,8 @@ public class TestTreeMapStore extends TestBase {
private
void
testSimple
()
{
String
fileName
=
getBaseDir
()
+
"/data.h3"
;
FileUtils
.
delete
(
fileName
);
TreeMapStore
s
=
T
reeMapStore
.
open
(
fileName
);
Stored
Map
<
Integer
,
String
>
m
=
s
.
openMap
(
"data"
,
Integer
.
class
,
String
.
class
);
BtreeMapStore
s
=
Bt
reeMapStore
.
open
(
fileName
);
Btree
Map
<
Integer
,
String
>
m
=
s
.
openMap
(
"data"
,
Integer
.
class
,
String
.
class
);
for
(
int
i
=
0
;
i
<
3
;
i
++)
{
m
.
put
(
i
,
"hello "
+
i
);
}
...
...
@@ -244,7 +238,7 @@ public class TestTreeMapStore extends TestBase {
s
.
close
();
s
=
T
reeMapStore
.
open
(
fileName
);
s
=
Bt
reeMapStore
.
open
(
fileName
);
m
=
s
.
openMap
(
"data"
,
Integer
.
class
,
String
.
class
);
assertNull
(
m
.
get
(
0
));
for
(
int
i
=
1
;
i
<
3
;
i
++)
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/tools/org/h2/dev/store/btree/BtreeMap.java
浏览文件 @
ac599513
...
...
@@ -90,7 +90,7 @@ public class BtreeMap<K, V> {
* Get a value.
*
* @param key the key
* @return the value
* @return the value
, or null if not found
*/
@SuppressWarnings
(
"unchecked"
)
public
V
get
(
K
key
)
{
...
...
@@ -100,6 +100,19 @@ public class BtreeMap<K, V> {
return
(
V
)
root
.
find
(
key
);
}
/**
* Get the page for the given value.
*
* @param key the key
* @return the value, or null if not found
*/
public
Page
getPage
(
K
key
)
{
if
(
root
==
null
)
{
return
null
;
}
return
root
.
findPage
(
key
);
}
/**
* Remove a key-value pair.
*
...
...
@@ -109,7 +122,9 @@ public class BtreeMap<K, V> {
if
(!
isChanged
())
{
store
.
markChanged
(
name
,
this
);
}
root
=
Page
.
remove
(
root
,
key
);
if
(
root
!=
null
)
{
root
=
Page
.
remove
(
root
,
key
);
}
}
/**
...
...
This diff is collapsed.
Click to expand it.
h2/src/tools/org/h2/dev/store/btree/BtreeMapStore.java
浏览文件 @
ac599513
...
...
@@ -7,7 +7,6 @@
package
org
.
h2
.
dev
.
store
.
btree
;
import
java.io.ByteArrayInputStream
;
import
java.io.File
;
import
java.io.IOException
;
import
java.nio.ByteBuffer
;
import
java.nio.channels.FileChannel
;
...
...
@@ -273,15 +272,16 @@ public class BtreeMapStore {
if
(
x
.
liveCount
==
0
)
{
meta
.
remove
(
"block."
+
x
.
id
);
}
else
{
meta
.
put
(
"block."
+
x
.
id
,
"temp
"
+
x
.
toString
());
meta
.
put
(
"block."
+
x
.
id
,
"temp
-
"
+
x
.
toString
());
}
}
// modifying the meta can itself affect the metadata
// TODO solve this in a better way
ArrayList
<
Integer
>
removedBlocks
=
New
.
arrayList
();
for
(
Block
x
:
new
ArrayList
<
Block
>(
blocks
.
values
()))
{
if
(
x
.
liveCount
==
0
)
{
meta
.
remove
(
"block."
+
x
.
id
);
blocks
.
remove
(
x
.
id
);
removedBlocks
.
add
(
x
.
id
);
}
else
{
meta
.
put
(
"block."
+
x
.
id
,
x
.
toString
());
}
...
...
@@ -289,7 +289,13 @@ public class BtreeMapStore {
lenEstimate
+=
meta
.
getRoot
().
lengthIncludingTempChildren
();
b
.
length
=
lenEstimate
;
blocks
.
remove
(
b
.
id
);
long
storePos
=
allocateBlock
(
lenEstimate
);
blocks
.
put
(
b
.
id
,
b
);
for
(
int
id
:
removedBlocks
)
{
blocks
.
remove
(
id
);
}
long
pageId
=
getId
(
blockId
,
1
+
8
);
for
(
BtreeMap
<?,
?>
m
:
mapsChanged
.
values
())
{
...
...
@@ -301,7 +307,6 @@ public class BtreeMapStore {
}
}
int
metaRootOffset
=
(
int
)
(
pageId
-
getId
(
blockId
,
0
));
// add a dummy entry so the count is correct
meta
.
put
(
"block."
+
b
.
id
,
b
.
toString
());
int
count
=
0
;
...
...
@@ -424,7 +429,6 @@ public class BtreeMapStore {
* be re-written.
*/
public
void
compact
()
{
if
(
true
)
throw
new
RuntimeException
(
"not implemented yet"
);
if
(
blocks
.
size
()
<=
1
)
{
return
;
}
...
...
@@ -473,7 +477,7 @@ public class BtreeMapStore {
}
long
oldMetaRootId
=
readMetaRootId
(
move
.
start
);
long
offset
=
getPosition
(
oldMetaRootId
);
log
(
" meta:"
+
move
.
id
+
"/"
+
offset
);
log
(
" meta:"
+
move
.
id
+
"/"
+
offset
+
" start: "
+
move
.
start
);
BtreeMap
<
String
,
String
>
oldMeta
=
BtreeMap
.
open
(
this
,
"old-meta"
,
String
.
class
,
String
.
class
);
oldMeta
.
setRoot
(
oldMetaRootId
);
Iterator
<
String
>
it
=
oldMeta
.
keyIterator
(
null
);
...
...
@@ -509,19 +513,19 @@ public class BtreeMapStore {
Iterator
<?>
dataIt
=
oldData
.
keyIterator
(
null
);
while
(
dataIt
.
hasNext
())
{
Object
o
=
dataIt
.
next
();
int
todo
;
Page
p
=
null
;
// data.getNode(o);
Page
p
=
data
.
getPage
(
o
);
if
(
p
==
null
)
{
// was removed later - ignore
}
else
if
(
p
.
getId
()
<
0
)
{
// temporarily changed - ok
// TODO move old data if changed temporarily?
}
else
{
Block
b
=
getBlock
(
p
.
getId
());
if
(
old
.
contains
(
b
))
{
log
(
" move key:"
+
o
+
" block:"
+
b
.
id
);
Object
value
=
data
.
get
(
o
);
data
.
remove
(
o
);
int
todo2
;
// data.put(o, n.getData());
data
.
put
(
o
,
value
);
}
}
}
...
...
@@ -657,6 +661,7 @@ public class BtreeMapStore {
* @param string the string to log
*/
public
void
log
(
String
string
)
{
// TODO logging
// System.out.println(string);
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/tools/org/h2/dev/store/btree/Page.java
浏览文件 @
ac599513
...
...
@@ -135,6 +135,29 @@ class Page {
return
null
;
}
/**
* Get the value for the given key, or null if not found.
*
* @param key the key
* @return the page or null
*/
Page
findPage
(
Object
key
)
{
int
x
=
findKey
(
key
);
if
(
children
!=
null
)
{
if
(
x
<
0
)
{
x
=
-
x
-
1
;
}
else
{
x
++;
}
Page
p
=
map
.
readPage
(
children
[
x
]);
return
p
.
findPage
(
key
);
}
if
(
x
>=
0
)
{
return
this
;
}
return
null
;
}
private
int
findKey
(
Object
key
)
{
int
low
=
0
,
high
=
keys
.
length
-
1
;
while
(
low
<=
high
)
{
...
...
@@ -175,7 +198,6 @@ class Page {
* @param key the key
*/
static
void
min
(
Page
p
,
ArrayList
<
CursorPos
>
parents
,
Object
key
)
{
int
todo
;
while
(
p
!=
null
)
{
int
x
=
key
==
null
?
0
:
p
.
findKey
(
key
);
if
(
p
.
children
!=
null
)
{
...
...
@@ -184,11 +206,11 @@ class Page {
}
else
{
x
++;
}
p
=
p
.
map
.
readPage
(
p
.
children
[
x
]);
CursorPos
c
=
new
CursorPos
();
c
.
page
=
p
;
c
.
index
=
x
;
parents
.
add
(
c
);
p
=
p
.
map
.
readPage
(
p
.
children
[
x
]);
}
else
{
if
(
x
<
0
)
{
x
=
-
x
-
1
;
...
...
@@ -209,12 +231,11 @@ class Page {
* @return the next key
*/
public
static
Object
nextKey
(
ArrayList
<
CursorPos
>
parents
)
{
int
todoTest
;
if
(
parents
.
size
()
==
0
)
{
return
null
;
}
while
(
true
)
{
// TODO avoid remove/add pairs i
s
possible
// TODO avoid remove/add pairs i
f
possible
CursorPos
p
=
parents
.
remove
(
parents
.
size
()
-
1
);
int
index
=
p
.
index
++;
if
(
index
<
p
.
page
.
keys
.
length
)
{
...
...
@@ -229,7 +250,9 @@ class Page {
index
=
p
.
index
++;
if
(
index
<
p
.
page
.
children
.
length
)
{
parents
.
add
(
p
);
min
(
p
.
page
,
parents
,
null
);
Page
x
=
p
.
page
;
x
=
x
.
map
.
readPage
(
x
.
children
[
index
]);
min
(
x
,
parents
,
null
);
break
;
}
}
...
...
@@ -321,6 +344,11 @@ class Page {
int
index
=
p
.
findKey
(
key
);
if
(
p
.
isLeaf
())
{
if
(
index
>=
0
)
{
// create a copy
// TODO might not be required, but needs a "modified" flag
Object
[]
v2
=
new
Object
[
p
.
values
.
length
];
System
.
arraycopy
(
p
.
values
,
0
,
v2
,
0
,
v2
.
length
);
p
.
values
=
v2
;
p
.
values
[
index
]
=
value
;
break
;
}
...
...
@@ -398,26 +426,6 @@ class Page {
return
top
;
}
/**
* Remove a key.
*
* @param key the key
* @return the new page or null if the page is now empty
*/
private
Page
remove
(
Object
key
)
{
int
index
=
findKey
(
key
);
if
(
isLeaf
())
{
if
(
index
<
0
)
{
// not found
return
this
;
}
}
Page
p
=
copyOnWrite
();
p
=
p
.
remove
(
key
);
return
p
;
}
private
void
insert
(
int
index
,
Object
key
,
Object
value
,
long
child
)
{
Object
[]
newKeys
=
new
Object
[
keys
.
length
+
1
];
copyWithGap
(
keys
,
newKeys
,
keys
.
length
,
index
);
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论