Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
49b85b79
提交
49b85b79
authored
12 年前
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
A persistent multi-version map: simplified cursor
上级
4b20cf9b
master
noel-pr1
plus33-master
pr/267
stumc-Issue#576
version-1.4.198
version-1.4.197
version-1.4.196
version-1.4.195
version-1.4.194
version-1.4.193
version-1.4.192
version-1.4.191
version-1.4.190
version-1.4.188
version-1.4.187
version-1.4.186
version-1.4.185
version-1.4.184
version-1.4.183
version-1.4.182
version-1.4.181
version-1.4.178
version-1.4.177
version-1.3
无相关合并请求
显示空白字符变更
内嵌
并排
正在显示
7 个修改的文件
包含
273 行增加
和
320 行删除
+273
-320
MVRTreeMap.java
h2/src/test/org/h2/test/store/MVRTreeMap.java
+5
-60
TestMVStore.java
h2/src/test/org/h2/test/store/TestMVStore.java
+4
-4
ChangeCursor.java
h2/src/tools/org/h2/dev/store/btree/ChangeCursor.java
+188
-29
Cursor.java
h2/src/tools/org/h2/dev/store/btree/Cursor.java
+47
-69
MVMap.java
h2/src/tools/org/h2/dev/store/btree/MVMap.java
+11
-69
Page.java
h2/src/tools/org/h2/dev/store/btree/Page.java
+18
-1
RangeCursor.java
h2/src/tools/org/h2/dev/store/btree/RangeCursor.java
+0
-88
没有找到文件。
h2/src/test/org/h2/test/store/MVRTreeMap.java
浏览文件 @
49b85b79
...
@@ -7,11 +7,9 @@
...
@@ -7,11 +7,9 @@
package
org
.
h2
.
test
.
store
;
package
org
.
h2
.
test
.
store
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
org.h2.dev.store.btree.DataType
;
import
org.h2.dev.store.btree.MVMap
;
import
org.h2.dev.store.btree.MVMap
;
import
org.h2.dev.store.btree.MVStore
;
import
org.h2.dev.store.btree.MVStore
;
import
org.h2.dev.store.btree.Cursor
;
import
org.h2.dev.store.btree.CursorPos
;
import
org.h2.dev.store.btree.DataType
;
import
org.h2.dev.store.btree.Page
;
import
org.h2.dev.store.btree.Page
;
import
org.h2.util.New
;
import
org.h2.util.New
;
...
@@ -399,63 +397,6 @@ public class MVRTreeMap<K, V> extends MVMap<K, V> {
...
@@ -399,63 +397,6 @@ public class MVRTreeMap<K, V> extends MVMap<K, V> {
}
}
}
}
/**
* Go to the first element for the given key.
*
* @param p the current page
* @param cursor the cursor
* @param key the key
* @return the cursor position
*/
protected
CursorPos
min
(
Page
p
,
Cursor
<
K
,
V
>
cursor
,
Object
key
)
{
if
(
p
==
null
)
{
return
null
;
}
while
(
true
)
{
CursorPos
c
=
new
CursorPos
(
p
,
0
,
null
);
if
(
p
.
isLeaf
())
{
return
c
;
}
cursor
.
push
(
c
);
p
=
p
.
getChildPage
(
0
);
}
}
/**
* Get the next key.
*
* @param p the cursor position
* @param cursor the cursor
* @return the next key
*/
protected
Object
nextKey
(
CursorPos
p
,
Cursor
<
K
,
V
>
cursor
)
{
while
(
p
!=
null
)
{
int
index
=
p
.
index
++;
Page
x
=
p
.
page
;
if
(
index
<
x
.
getKeyCount
())
{
return
x
.
getKey
(
index
);
}
while
(
true
)
{
p
=
cursor
.
pop
();
if
(
p
==
null
)
{
break
;
}
index
=
++
p
.
index
;
x
=
p
.
page
;
// this is different from a b-tree:
// we have one less child
if
(
index
<
x
.
getKeyCount
())
{
cursor
.
push
(
p
);
p
=
cursor
.
visitChild
(
x
,
index
);
if
(
p
!=
null
)
{
break
;
}
}
}
}
return
null
;
}
public
boolean
isQuadraticSplit
()
{
public
boolean
isQuadraticSplit
()
{
return
quadraticSplit
;
return
quadraticSplit
;
}
}
...
@@ -464,4 +405,8 @@ public class MVRTreeMap<K, V> extends MVMap<K, V> {
...
@@ -464,4 +405,8 @@ public class MVRTreeMap<K, V> extends MVMap<K, V> {
this
.
quadraticSplit
=
quadraticSplit
;
this
.
quadraticSplit
=
quadraticSplit
;
}
}
protected
int
getChildPageCount
(
Page
p
)
{
return
p
.
getChildPageCount
()
-
1
;
}
}
}
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/store/TestMVStore.java
浏览文件 @
49b85b79
...
@@ -184,21 +184,21 @@ public class TestMVStore extends TestBase {
...
@@ -184,21 +184,21 @@ public class TestMVStore extends TestBase {
for
(
int
i
=
20
;
i
<
40
;
i
++)
{
for
(
int
i
=
20
;
i
<
40
;
i
++)
{
assertEquals
(
"Hi"
,
m
.
put
(
i
,
"Hello"
));
assertEquals
(
"Hi"
,
m
.
put
(
i
,
"Hello"
));
}
}
s
.
incrementVersion
();
long
old
=
s
.
incrementVersion
();
for
(
int
i
=
10
;
i
<
15
;
i
++)
{
for
(
int
i
=
10
;
i
<
15
;
i
++)
{
m
.
put
(
i
,
"Hallo"
);
m
.
put
(
i
,
"Hallo"
);
}
}
m
.
put
(
50
,
"Hallo"
);
m
.
put
(
50
,
"Hallo"
);
for
(
int
i
=
90
;
i
<
100
;
i
++)
{
for
(
int
i
=
90
;
i
<
93
;
i
++)
{
assertEquals
(
"Hi"
,
m
.
remove
(
i
));
assertEquals
(
"Hi"
,
m
.
remove
(
i
));
}
}
assertEquals
(
null
,
m
.
put
(
100
,
"Hallo"
));
assertEquals
(
null
,
m
.
put
(
100
,
"Hallo"
));
Iterator
<
Integer
>
it
=
m
.
changeIterator
(
s
.
getCurrentVersion
()
);
Iterator
<
Integer
>
it
=
m
.
changeIterator
(
old
);
ArrayList
<
Integer
>
list
=
New
.
arrayList
();
ArrayList
<
Integer
>
list
=
New
.
arrayList
();
while
(
it
.
hasNext
())
{
while
(
it
.
hasNext
())
{
list
.
add
(
it
.
next
());
list
.
add
(
it
.
next
());
}
}
assertEquals
(
"[
9, 10, 11, 12, 13, 14, 48, 49, 50, 87, 88, 89, 100
]"
,
list
.
toString
());
assertEquals
(
"[
10, 11, 12, 13, 14, 50, 100, 90, 91, 92
]"
,
list
.
toString
());
s
.
close
();
s
.
close
();
}
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/tools/org/h2/dev/store/btree/ChangeCursor.java
浏览文件 @
49b85b79
...
@@ -6,57 +6,216 @@
...
@@ -6,57 +6,216 @@
*/
*/
package
org
.
h2
.
dev
.
store
.
btree
;
package
org
.
h2
.
dev
.
store
.
btree
;
import
java.util.Iterator
;
/**
/**
* A cursor to iterate over all keys in new pages.
* A cursor to iterate over all keys in new pages.
*
*
* @param <K> the key type
* @param <K> the key type
* @param <V> the value type
* @param <V> the value type
*/
*/
public
class
ChangeCursor
<
K
,
V
>
extends
Cursor
<
K
,
V
>
{
public
class
ChangeCursor
<
K
,
V
>
implements
Iterator
<
K
>
{
private
final
MVMap
<
K
,
V
>
map
;
private
final
Page
root1
,
root2
;
private
final
long
minVersion
;
/**
* The state of this cursor.
* 0: not initialized
* 1: reading from root1
* 2: reading from root2
* 3: closed
*/
private
int
state
;
private
CursorPos
pos1
,
pos2
;
private
K
current
;
ChangeCursor
(
MVMap
<
K
,
V
>
map
,
Page
root
,
K
from
,
long
minVersion
)
{
ChangeCursor
(
MVMap
<
K
,
V
>
map
,
Page
root1
,
Page
root2
)
{
super
(
map
,
root
,
from
);
this
.
map
=
map
;
this
.
minVersion
=
minVersion
;
this
.
root1
=
root1
;
this
.
root2
=
root2
;
}
}
public
CursorPos
min
(
Page
p
,
K
from
)
{
public
K
next
()
{
while
(
p
!=
null
&&
p
.
getVersion
()
>=
minVersion
)
{
K
c
=
current
;
if
(
p
.
isLeaf
())
{
fetchNext
();
return
new
CursorPos
(
p
,
0
,
null
);
return
c
;
}
public
boolean
hasNext
()
{
if
(
state
==
0
)
{
pos1
=
new
CursorPos
(
root1
,
0
,
null
);
pos1
=
min
(
pos1
);
state
=
1
;
fetchNext
();
}
return
current
!=
null
;
}
public
void
remove
()
{
throw
new
UnsupportedOperationException
();
}
private
void
fetchNext
()
{
while
(
fetchNextKey
())
{
if
(
pos1
==
null
||
pos2
==
null
)
{
break
;
}
@SuppressWarnings
(
"unchecked"
)
V
v1
=
(
V
)
map
.
binarySearch
(
root1
,
current
);
@SuppressWarnings
(
"unchecked"
)
V
v2
=
(
V
)
map
.
binarySearch
(
root2
,
current
);
if
(!
v1
.
equals
(
v2
))
{
break
;
}
}
}
for
(
int
i
=
0
;
i
<
p
.
getChildPageCount
();
i
++)
{
}
if
(
isChildOld
(
p
,
i
))
{
private
boolean
fetchNextKey
()
{
while
(
true
)
{
if
(
state
==
3
)
{
return
false
;
}
if
(
state
==
1
)
{
// read from root1
pos1
=
fetchNext
(
pos1
);
if
(
pos1
==
null
)
{
// reached the end of pos1
state
=
2
;
pos2
=
null
;
continue
;
continue
;
}
}
CursorPos
c
=
new
CursorPos
(
p
,
i
,
null
);
pos2
=
find
(
root2
,
current
);
push
(
c
);
if
(
pos2
==
null
)
{
p
=
p
.
getChildPage
(
i
);
// not found in root2
return
true
;
}
if
(!
pos1
.
page
.
equals
(
pos2
.
page
))
{
// the page is different,
// so the entry has possibly changed
return
true
;
}
while
(
true
)
{
pos1
=
pos1
.
parent
;
if
(
pos1
==
null
)
{
// reached end of pos1
state
=
2
;
pos2
=
null
;
break
;
}
pos2
=
pos2
.
parent
;
if
(
pos2
==
null
||
!
pos1
.
page
.
equals
(
pos2
.
page
.
getPos
()))
{
if
(
pos1
.
index
+
1
<
map
.
getChildPageCount
(
pos1
.
page
))
{
pos1
=
new
CursorPos
(
pos1
.
page
.
getChildPage
(++
pos1
.
index
),
0
,
pos1
);
pos1
=
min
(
pos1
);
break
;
break
;
}
}
}
}
return
null
;
}
}
if
(
state
==
2
)
{
if
(
pos2
==
null
)
{
// init reading from root2
pos2
=
new
CursorPos
(
root2
,
0
,
null
);
pos2
=
min
(
pos2
);
}
// read from root2
pos2
=
fetchNext
(
pos2
);
if
(
pos2
==
null
)
{
// reached the end of pos2
state
=
3
;
current
=
null
;
continue
;
}
pos1
=
find
(
root1
,
current
);
if
(
pos1
!=
null
)
{
// found a corresponding record
// so it was not deleted
// but now we may need to skip pages
if
(!
pos1
.
page
.
equals
(
pos2
.
page
))
{
// the page is different
pos1
=
null
;
continue
;
}
while
(
true
)
{
pos2
=
pos2
.
parent
;
if
(
pos2
==
null
)
{
// reached end of pos1
state
=
3
;
current
=
null
;
pos1
=
null
;
break
;
}
pos1
=
pos1
.
parent
;
if
(
pos1
==
null
||
!
pos2
.
page
.
equals
(
pos1
.
page
.
getPos
()))
{
if
(
pos2
.
index
+
1
<
map
.
getChildPageCount
(
pos2
.
page
))
{
pos2
=
new
CursorPos
(
pos2
.
page
.
getChildPage
(++
pos2
.
index
),
0
,
pos2
);
pos2
=
min
(
pos2
);
break
;
}
}
}
pos1
=
null
;
continue
;
}
// found no corresponding record
// so it was deleted
return
true
;
}
}
}
}
public
CursorPos
visitChild
(
Page
p
,
int
childIndex
)
{
private
CursorPos
find
(
Page
p
,
K
key
)
{
if
(
isChildOld
(
p
,
childIndex
))
{
// TODO combine with RangeCursor.min
// possibly move to MVMap
CursorPos
pos
=
null
;
while
(
true
)
{
if
(
p
.
isLeaf
())
{
int
x
=
key
==
null
?
0
:
p
.
binarySearch
(
key
);
if
(
x
<
0
)
{
return
null
;
return
null
;
}
}
return
super
.
visitChild
(
p
,
childIndex
);
return
new
CursorPos
(
p
,
x
,
pos
);
}
int
x
=
key
==
null
?
-
1
:
p
.
binarySearch
(
key
);
if
(
x
<
0
)
{
x
=
-
x
-
1
;
}
else
{
x
++;
}
pos
=
new
CursorPos
(
p
,
x
,
pos
);
p
=
p
.
getChildPage
(
x
);
}
}
}
private
boolean
isChildOld
(
Page
p
,
int
childIndex
)
{
@SuppressWarnings
(
"unchecked"
)
long
pos
=
p
.
getChildPagePos
(
childIndex
);
private
CursorPos
fetchNext
(
CursorPos
p
)
{
if
(
pos
==
0
)
{
while
(
p
!=
null
)
{
Page
c
=
p
.
getChildPage
(
childIndex
);
if
(
p
.
index
<
p
.
page
.
getKeyCount
())
{
if
(
c
.
getVersion
()
<
minVersion
)
{
current
=
(
K
)
p
.
page
.
getKey
(
p
.
index
++);
return
true
;
return
p
;
}
}
}
else
if
(
map
.
getStore
().
getChunk
(
pos
).
version
<
minVersion
)
{
p
=
p
.
parent
;
return
true
;
if
(
p
==
null
)
{
break
;
}
if
(
p
.
index
+
1
<
map
.
getChildPageCount
(
p
.
page
))
{
p
=
new
CursorPos
(
p
.
page
.
getChildPage
(++
p
.
index
),
0
,
p
);
p
=
min
(
p
);
}
}
current
=
null
;
return
p
;
}
private
static
CursorPos
min
(
CursorPos
p
)
{
while
(
true
)
{
if
(
p
.
page
.
isLeaf
())
{
return
p
;
}
Page
c
=
p
.
page
.
getChildPage
(
0
);
p
=
new
CursorPos
(
c
,
0
,
p
);
}
}
return
false
;
}
}
}
}
This diff is collapsed.
Click to expand it.
h2/src/tools/org/h2/dev/store/btree/Cursor.java
浏览文件 @
49b85b79
...
@@ -6,7 +6,6 @@
...
@@ -6,7 +6,6 @@
*/
*/
package
org
.
h2
.
dev
.
store
.
btree
;
package
org
.
h2
.
dev
.
store
.
btree
;
import
java.util.ArrayList
;
import
java.util.Iterator
;
import
java.util.Iterator
;
/**
/**
...
@@ -17,12 +16,11 @@ import java.util.Iterator;
...
@@ -17,12 +16,11 @@ import java.util.Iterator;
*/
*/
public
class
Cursor
<
K
,
V
>
implements
Iterator
<
K
>
{
public
class
Cursor
<
K
,
V
>
implements
Iterator
<
K
>
{
protected
final
MVMap
<
K
,
V
>
map
;
private
final
MVMap
<
K
,
V
>
map
;
protected
final
Page
root
;
private
final
K
from
;
protected
final
K
from
;
private
Page
root
;
protected
ArrayList
<
CursorPos
>
parents
;
private
CursorPos
pos
;
protected
CursorPos
currentPos
;
private
K
current
;
protected
K
current
;
Cursor
(
MVMap
<
K
,
V
>
map
,
Page
root
,
K
from
)
{
Cursor
(
MVMap
<
K
,
V
>
map
,
Page
root
,
K
from
)
{
this
.
map
=
map
;
this
.
map
=
map
;
...
@@ -31,33 +29,18 @@ public class Cursor<K, V> implements Iterator<K> {
...
@@ -31,33 +29,18 @@ public class Cursor<K, V> implements Iterator<K> {
}
}
public
K
next
()
{
public
K
next
()
{
if
(!
hasNext
())
{
return
null
;
}
K
c
=
current
;
K
c
=
current
;
if
(
c
!=
null
)
{
fetchNext
();
fetchNext
();
}
return
c
;
return
c
==
null
?
null
:
c
;
}
/**
* Fetch the next key.
*/
@SuppressWarnings
(
"unchecked"
)
protected
void
fetchNext
()
{
current
=
(
K
)
map
.
nextKey
(
currentPos
,
this
);
}
}
public
boolean
hasNext
()
{
public
boolean
hasNext
()
{
if
(
parents
==
null
)
{
if
(
root
!=
null
)
{
// not initialized yet: fetch the first key
// initialize
parents
=
new
ArrayList
<
CursorPos
>();
min
(
root
,
from
);
currentPos
=
min
(
root
,
from
);
root
=
null
;
if
(
currentPos
!=
null
)
{
fetchNext
();
fetchNext
();
}
}
}
return
current
!=
null
;
return
current
!=
null
;
}
}
...
@@ -65,48 +48,43 @@ public class Cursor<K, V> implements Iterator<K> {
...
@@ -65,48 +48,43 @@ public class Cursor<K, V> implements Iterator<K> {
throw
new
UnsupportedOperationException
();
throw
new
UnsupportedOperationException
();
}
}
/**
private
void
min
(
Page
p
,
K
from
)
{
* Add a cursor position to the stack.
while
(
true
)
{
*
if
(
p
.
isLeaf
())
{
* @param p the cursor position
int
x
=
from
==
null
?
0
:
p
.
binarySearch
(
from
);
*/
if
(
x
<
0
)
{
public
void
push
(
CursorPos
p
)
{
x
=
-
x
-
1
;
parents
.
add
(
p
);
}
}
pos
=
new
CursorPos
(
p
,
x
,
pos
);
/**
break
;
* Remove the latest cursor position from the stack and return it.
}
*
int
x
=
from
==
null
?
-
1
:
p
.
binarySearch
(
from
);
* @return the cursor position, or null if none
if
(
x
<
0
)
{
*/
x
=
-
x
-
1
;
public
CursorPos
pop
()
{
}
else
{
int
size
=
parents
.
size
();
x
++;
return
size
==
0
?
null
:
parents
.
remove
(
size
-
1
);
}
pos
=
new
CursorPos
(
p
,
x
+
1
,
pos
);
p
=
p
.
getChildPage
(
x
);
}
}
/**
* Visit the first key that is greater or equal the given key.
*
* @param p the page
* @param from the key, or null
* @return the cursor position
*/
public
CursorPos
min
(
Page
p
,
K
from
)
{
return
map
.
min
(
p
,
this
,
from
);
}
}
/**
@SuppressWarnings
(
"unchecked"
)
* Visit the first key within this child page.
private
void
fetchNext
()
{
*
while
(
pos
!=
null
)
{
* @param p the page
if
(
pos
.
index
<
pos
.
page
.
getKeyCount
())
{
* @param childIndex the child index
current
=
(
K
)
pos
.
page
.
getKey
(
pos
.
index
++);
* @return the cursor position
return
;
*/
}
public
CursorPos
visitChild
(
Page
p
,
int
childIndex
)
{
pos
=
pos
.
parent
;
p
=
p
.
getChildPage
(
childIndex
);
if
(
pos
==
null
)
{
currentPos
=
min
(
p
,
null
);
break
;
return
currentPos
;
}
if
(
pos
.
index
<
map
.
getChildPageCount
(
pos
.
page
))
{
min
(
pos
.
page
.
getChildPage
(
pos
.
index
++),
null
);
}
}
current
=
null
;
}
}
}
}
This diff is collapsed.
Click to expand it.
h2/src/tools/org/h2/dev/store/btree/MVMap.java
浏览文件 @
49b85b79
...
@@ -137,68 +137,6 @@ public class MVMap<K, V> extends AbstractMap<K, V> {
...
@@ -137,68 +137,6 @@ public class MVMap<K, V> extends AbstractMap<K, V> {
return
(
V
)
binarySearch
(
root
,
key
);
return
(
V
)
binarySearch
(
root
,
key
);
}
}
/**
* Go to the first element for the given key.
*
* @param p the current page
* @param cursor the cursor
* @param key the key
* @return the cursor position
*/
protected
CursorPos
min
(
Page
p
,
Cursor
<
K
,
V
>
cursor
,
Object
key
)
{
while
(
true
)
{
if
(
p
.
isLeaf
())
{
int
x
=
key
==
null
?
0
:
p
.
binarySearch
(
key
);
if
(
x
<
0
)
{
x
=
-
x
-
1
;
}
return
new
CursorPos
(
p
,
x
,
null
);
}
int
x
=
key
==
null
?
-
1
:
p
.
binarySearch
(
key
);
if
(
x
<
0
)
{
x
=
-
x
-
1
;
}
else
{
x
++;
}
CursorPos
c
=
new
CursorPos
(
p
,
x
,
null
);
cursor
.
push
(
c
);
p
=
p
.
getChildPage
(
x
);
}
}
/**
* Get the next key.
*
* @param p the cursor position
* @param cursor the cursor
* @return the next key
*/
protected
Object
nextKey
(
CursorPos
p
,
Cursor
<
K
,
V
>
cursor
)
{
while
(
p
!=
null
)
{
int
index
=
p
.
index
++;
Page
x
=
p
.
page
;
if
(
index
<
x
.
getKeyCount
())
{
return
x
.
getKey
(
index
);
}
while
(
true
)
{
p
=
cursor
.
pop
();
if
(
p
==
null
)
{
break
;
}
index
=
++
p
.
index
;
x
=
p
.
page
;
if
(
index
<=
x
.
getKeyCount
())
{
cursor
.
push
(
p
);
p
=
cursor
.
visitChild
(
x
,
index
);
if
(
p
!=
null
)
{
break
;
}
}
}
}
return
null
;
}
/**
/**
* Get the value for the given key, or null if not found.
* Get the value for the given key, or null if not found.
*
*
...
@@ -443,20 +381,20 @@ public class MVMap<K, V> extends AbstractMap<K, V> {
...
@@ -443,20 +381,20 @@ public class MVMap<K, V> extends AbstractMap<K, V> {
*/
*/
public
Iterator
<
K
>
keyIterator
(
K
from
)
{
public
Iterator
<
K
>
keyIterator
(
K
from
)
{
checkOpen
();
checkOpen
();
return
new
RangeCursor
<
K
,
V
>(
root
,
from
);
return
new
Cursor
<
K
,
V
>(
this
,
root
,
from
);
// return new Cursor<K, V>(this, root, from);
// return new Cursor<K, V>(this, root, from);
}
}
/**
/**
* Iterate over all keys in changed pages.
* Iterate over all keys in changed pages.
* This does not include deleted deleted pages.
*
*
* @param
minVersion the minimum
version
* @param
version the old
version
* @return the iterator
* @return the iterator
*/
*/
public
Iterator
<
K
>
changeIterator
(
long
minV
ersion
)
{
public
Iterator
<
K
>
changeIterator
(
long
v
ersion
)
{
checkOpen
();
checkOpen
();
return
new
ChangeCursor
<
K
,
V
>(
this
,
root
,
null
,
minVersion
);
MVMap
<
K
,
V
>
old
=
openVersion
(
version
);
return
new
ChangeCursor
<
K
,
V
>(
this
,
root
,
old
.
root
);
}
}
public
Set
<
Map
.
Entry
<
K
,
V
>>
entrySet
()
{
public
Set
<
Map
.
Entry
<
K
,
V
>>
entrySet
()
{
...
@@ -469,13 +407,13 @@ public class MVMap<K, V> extends AbstractMap<K, V> {
...
@@ -469,13 +407,13 @@ public class MVMap<K, V> extends AbstractMap<K, V> {
public
Set
<
K
>
keySet
()
{
public
Set
<
K
>
keySet
()
{
checkOpen
();
checkOpen
();
final
MVMap
<
K
,
V
>
map
=
this
;
final
Page
root
=
this
.
root
;
final
Page
root
=
this
.
root
;
return
new
AbstractSet
<
K
>()
{
return
new
AbstractSet
<
K
>()
{
@Override
@Override
public
Iterator
<
K
>
iterator
()
{
public
Iterator
<
K
>
iterator
()
{
return
new
RangeCursor
<
K
,
V
>(
root
,
null
);
return
new
Cursor
<
K
,
V
>(
map
,
root
,
null
);
// return new Cursor<K, V>(MVMap.this, root, null);
}
}
@Override
@Override
...
@@ -701,4 +639,8 @@ public class MVMap<K, V> extends AbstractMap<K, V> {
...
@@ -701,4 +639,8 @@ public class MVMap<K, V> extends AbstractMap<K, V> {
return
root
.
getVersion
();
return
root
.
getVersion
();
}
}
protected
int
getChildPageCount
(
Page
p
)
{
return
p
.
getChildPageCount
();
}
}
}
This diff is collapsed.
Click to expand it.
h2/src/tools/org/h2/dev/store/btree/Page.java
浏览文件 @
49b85b79
...
@@ -788,8 +788,25 @@ public class Page {
...
@@ -788,8 +788,25 @@ public class Page {
return
version
;
return
version
;
}
}
int
getChildPageCount
()
{
public
int
getChildPageCount
()
{
return
children
.
length
;
return
children
.
length
;
}
}
public
boolean
equals
(
Object
other
)
{
if
(
other
==
this
)
{
return
true
;
}
if
(
other
instanceof
Page
)
{
if
(
pos
!=
0
&&
((
Page
)
other
).
pos
==
pos
)
{
return
true
;
}
return
this
==
other
;
}
return
false
;
}
public
int
hashCode
()
{
return
pos
!=
0
?
(
int
)
(
pos
|
(
pos
>>>
32
))
:
super
.
hashCode
();
}
}
}
This diff is collapsed.
Click to expand it.
h2/src/tools/org/h2/dev/store/btree/RangeCursor.java
deleted
100644 → 0
浏览文件 @
4b20cf9b
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
dev
.
store
.
btree
;
import
java.util.Iterator
;
/**
* A cursor to iterate over elements in ascending order.
*
* @param <K> the key type
* @param <V> the value type
*/
public
class
RangeCursor
<
K
,
V
>
implements
Iterator
<
K
>
{
protected
final
K
from
;
protected
Page
root
;
protected
CursorPos
pos
;
protected
K
current
;
RangeCursor
(
Page
root
,
K
from
)
{
this
.
root
=
root
;
this
.
from
=
from
;
}
public
K
next
()
{
K
c
=
current
;
fetchNext
();
return
c
;
}
public
boolean
hasNext
()
{
if
(
root
!=
null
)
{
// initialize
min
(
root
,
from
);
root
=
null
;
fetchNext
();
}
return
current
!=
null
;
}
public
void
remove
()
{
throw
new
UnsupportedOperationException
();
}
private
void
min
(
Page
p
,
K
from
)
{
while
(
true
)
{
if
(
p
.
isLeaf
())
{
int
x
=
from
==
null
?
0
:
p
.
binarySearch
(
from
);
if
(
x
<
0
)
{
x
=
-
x
-
1
;
}
pos
=
new
CursorPos
(
p
,
x
,
pos
);
break
;
}
int
x
=
from
==
null
?
-
1
:
p
.
binarySearch
(
from
);
if
(
x
<
0
)
{
x
=
-
x
-
1
;
}
else
{
x
++;
}
pos
=
new
CursorPos
(
p
,
x
+
1
,
pos
);
p
=
p
.
getChildPage
(
x
);
}
}
@SuppressWarnings
(
"unchecked"
)
private
void
fetchNext
()
{
while
(
pos
!=
null
)
{
if
(
pos
.
index
<
pos
.
page
.
getKeyCount
())
{
current
=
(
K
)
pos
.
page
.
getKey
(
pos
.
index
++);
return
;
}
pos
=
pos
.
parent
;
if
(
pos
==
null
)
{
break
;
}
if
(
pos
.
index
<
pos
.
page
.
getChildPageCount
())
{
min
(
pos
.
page
.
getChildPage
(
pos
.
index
++),
null
);
}
}
current
=
null
;
}
}
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论