Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
1217a01e
提交
1217a01e
authored
12 年前
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
A persistent multi-version map (work in progress): r-tree
上级
747b2489
隐藏空白字符变更
内嵌
并排
正在显示
5 个修改的文件
包含
185 行增加
和
108 行删除
+185
-108
RtreeMap.java
h2/src/test/org/h2/test/store/RtreeMap.java
+57
-41
SpatialKey.java
h2/src/test/org/h2/test/store/SpatialKey.java
+43
-15
SpatialType.java
h2/src/test/org/h2/test/store/SpatialType.java
+54
-31
BtreeMap.java
h2/src/tools/org/h2/dev/store/btree/BtreeMap.java
+11
-17
Cursor.java
h2/src/tools/org/h2/dev/store/btree/Cursor.java
+20
-4
没有找到文件。
h2/src/test/org/h2/test/store/RtreeMap.java
浏览文件 @
1217a01e
...
...
@@ -9,6 +9,7 @@ package org.h2.test.store;
import
java.util.ArrayList
;
import
org.h2.dev.store.btree.BtreeMap
;
import
org.h2.dev.store.btree.BtreeMapStore
;
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
;
...
...
@@ -35,7 +36,7 @@ public class RtreeMap<K, V> extends BtreeMap<K, V> {
if
(
root
==
null
)
{
return
null
;
}
return
(
V
)
get
Spatial
(
root
,
key
);
return
(
V
)
get
(
root
,
key
);
}
private
boolean
contains
(
Page
p
,
int
index
,
Object
key
)
{
...
...
@@ -53,11 +54,11 @@ public class RtreeMap<K, V> extends BtreeMap<K, V> {
* @param key the key
* @return the value, or null if not found
*/
protected
Object
get
Spatial
(
Page
p
,
Object
key
)
{
protected
Object
get
(
Page
p
,
Object
key
)
{
if
(!
p
.
isLeaf
())
{
for
(
int
i
=
0
;
i
<
p
.
getKeyCount
();
i
++)
{
if
(
contains
(
p
,
i
,
key
))
{
Object
o
=
get
Spatial
(
p
.
getChildPage
(
i
),
key
);
Object
o
=
get
(
p
.
getChildPage
(
i
),
key
);
if
(
o
!=
null
)
{
return
o
;
}
...
...
@@ -77,14 +78,14 @@ public class RtreeMap<K, V> extends BtreeMap<K, V> {
if
(
root
==
null
)
{
return
null
;
}
return
getPage
Spatial
(
root
,
key
);
return
getPage
(
root
,
key
);
}
protected
Page
getPage
Spatial
(
Page
p
,
Object
key
)
{
protected
Page
getPage
(
Page
p
,
Object
key
)
{
if
(!
p
.
isLeaf
())
{
for
(
int
i
=
0
;
i
<
p
.
getKeyCount
();
i
++)
{
if
(
contains
(
p
,
i
,
key
))
{
Page
x
=
getPage
Spatial
(
p
.
getChildPage
(
i
),
key
);
Page
x
=
getPage
(
p
.
getChildPage
(
i
),
key
);
if
(
x
!=
null
)
{
return
x
;
}
...
...
@@ -111,7 +112,7 @@ public class RtreeMap<K, V> extends BtreeMap<K, V> {
Page
c2
=
set
(
c
,
writeVersion
,
key
,
value
);
if
(
c
!=
c2
)
{
p
=
p
.
copyOnWrite
(
writeVersion
);
setChildUpdateBox
(
p
,
i
,
c2
);
setChildUpdateBox
(
p
,
i
,
c2
,
key
);
break
;
}
}
...
...
@@ -136,10 +137,18 @@ public class RtreeMap<K, V> extends BtreeMap<K, V> {
for
(
int
i
=
0
;
i
<
p
.
getKeyCount
();
i
++)
{
if
(
contains
(
p
,
i
,
key
))
{
Page
c
=
p
.
getChildPage
(
i
);
long
oldSize
=
c
.
getTotalSize
();
Page
c2
=
removeExisting
(
c
,
writeVersion
,
key
);
if
(
c
!=
c2
)
{
if
(
c2
==
null
)
{
// this child was deleted
p
.
remove
(
i
);
if
(
p
.
getKeyCount
()
==
0
)
{
removePage
(
p
);
return
null
;
}
}
else
if
(
oldSize
!=
c2
.
getTotalSize
())
{
p
=
p
.
copyOnWrite
(
writeVersion
);
setChildUpdateBox
(
p
,
i
,
c2
);
setChildUpdateBox
(
p
,
i
,
c2
,
key
);
break
;
}
}
...
...
@@ -147,6 +156,10 @@ public class RtreeMap<K, V> extends BtreeMap<K, V> {
}
else
{
for
(
int
i
=
0
;
i
<
p
.
getKeyCount
();
i
++)
{
if
(
keyType
.
equals
(
p
.
getKey
(
i
),
key
))
{
if
(
p
.
getKeyCount
()
==
1
)
{
removePage
(
p
);
return
null
;
}
p
=
p
.
copyOnWrite
(
writeVersion
);
p
.
remove
(
i
);
break
;
...
...
@@ -157,21 +170,26 @@ public class RtreeMap<K, V> extends BtreeMap<K, V> {
}
/**
* Set the child and update the bounding box.
* Set the child and update the bounding box if required. The bounding box
* is only updated if the key touches or is outside the old bounding box.
*
* @param p the parent (this page is changed)
* @param index the child index
* @param c the child page
* @param key the new or old key
*/
private
void
setChildUpdateBox
(
Page
p
,
int
index
,
Page
c
)
{
p
.
setKey
(
index
,
getBounds
(
c
));
private
void
setChildUpdateBox
(
Page
p
,
int
index
,
Page
c
,
Object
key
)
{
Object
oldBounds
=
p
.
getKey
(
index
);
if
(
key
==
null
||
!
keyType
.
isInside
(
key
,
oldBounds
))
{
p
.
setKey
(
index
,
getBounds
(
c
));
}
p
.
setChild
(
index
,
c
);
}
private
SpatialKey
getBounds
(
Page
x
)
{
SpatialKey
bounds
=
keyType
.
copy
((
SpatialKey
)
x
.
getKey
(
0
));
private
Object
getBounds
(
Page
x
)
{
Object
bounds
=
keyType
.
createBoundingBox
(
x
.
getKey
(
0
));
for
(
int
i
=
1
;
i
<
x
.
getKeyCount
();
i
++)
{
keyType
.
increase
(
bounds
,
(
SpatialKey
)
x
.
getKey
(
i
));
keyType
.
increase
Bounds
(
bounds
,
x
.
getKey
(
i
));
}
return
bounds
;
}
...
...
@@ -221,15 +239,15 @@ public class RtreeMap<K, V> extends BtreeMap<K, V> {
c
=
c
.
copyOnWrite
(
writeVersion
);
Page
split
=
split
(
c
,
writeVersion
);
p
=
p
.
copyOnWrite
(
writeVersion
);
setChildUpdateBox
(
p
,
index
,
c
);
setChildUpdateBox
(
p
,
index
,
c
,
null
);
p
.
insert
(
index
,
getBounds
(
split
),
null
,
split
.
getPos
(),
split
.
getTotalSize
());
// now we are not sure where to add
return
add
(
p
,
writeVersion
,
key
,
value
);
}
Page
c2
=
add
(
c
,
writeVersion
,
key
,
value
);
p
=
p
.
copyOnWrite
(
writeVersion
);
// the child might be the same, but
not the size
setChildUpdateBox
(
p
,
index
,
c2
);
// the child might be the same, but
maybe not the bounding box
setChildUpdateBox
(
p
,
index
,
c2
,
key
);
return
p
;
}
...
...
@@ -266,8 +284,8 @@ public class RtreeMap<K, V> extends BtreeMap<K, V> {
while
(
p
.
getKeyCount
()
>
0
)
{
float
diff
=
0
,
bestA
=
0
,
bestB
=
0
;
int
best
=
0
;
SpatialKey
ba
=
getBounds
(
newP
);
SpatialKey
bb
=
getBounds
(
split
);
Object
ba
=
getBounds
(
newP
);
Object
bb
=
getBounds
(
split
);
for
(
int
i
=
0
;
i
<
p
.
getKeyCount
();
i
++)
{
Object
o
=
p
.
getKey
(
i
);
float
a
=
keyType
.
getAreaIncrease
(
ba
,
o
);
...
...
@@ -301,10 +319,11 @@ public class RtreeMap<K, V> extends BtreeMap<K, V> {
source
.
remove
(
sourceIndex
);
}
public
void
addNodeKeys
(
ArrayList
<
SpatialKey
>
list
,
Page
p
)
{
@SuppressWarnings
(
"unchecked"
)
public
void
addNodeKeys
(
ArrayList
<
K
>
list
,
Page
p
)
{
if
(
p
!=
null
&&
!
p
.
isLeaf
())
{
for
(
int
i
=
0
;
i
<
p
.
getKeyCount
();
i
++)
{
list
.
add
((
SpatialKey
)
p
.
getKey
(
i
));
list
.
add
((
K
)
p
.
getKey
(
i
));
addNodeKeys
(
list
,
p
.
getChildPage
(
i
));
}
}
...
...
@@ -317,16 +336,17 @@ public class RtreeMap<K, V> extends BtreeMap<K, V> {
* @param parents the stack of parent page positions
* @param key the key
*/
protected
void
min
(
Page
p
,
ArrayList
<
CursorPos
>
parents
,
Object
key
)
{
protected
CursorPos
min
(
Page
p
,
Cursor
<
K
,
V
>
cursor
,
Object
key
)
{
while
(
p
!=
null
)
{
CursorPos
c
=
new
CursorPos
();
c
.
page
=
p
;
parents
.
add
(
c
);
if
(
p
.
isLeaf
())
{
return
;
return
c
;
}
cursor
.
push
(
c
);
p
=
p
.
getChildPage
(
0
);
}
return
null
;
}
/**
...
...
@@ -335,29 +355,25 @@ public class RtreeMap<K, V> extends BtreeMap<K, V> {
* @param parents the stack of parent page positions
* @return the next key
*/
protected
Object
nextKey
(
ArrayList
<
CursorPos
>
parents
)
{
if
(
parents
.
size
()
==
0
)
{
return
null
;
}
protected
Object
nextKey
(
CursorPos
p
,
Cursor
<
K
,
V
>
cursor
)
{
while
(
true
)
{
// TODO performance: avoid remove/add pairs if possible
CursorPos
p
=
parents
.
remove
(
parents
.
size
()
-
1
);
int
index
=
p
.
index
++;
if
(
index
<
p
.
page
.
getKeyCount
())
{
parents
.
add
(
p
);
return
p
.
page
.
getKey
(
index
);
Page
x
=
p
.
page
;
if
(
index
<
x
.
getKeyCount
())
{
return
x
.
getKey
(
index
);
}
while
(
true
)
{
if
(
parents
.
size
()
==
0
)
{
p
=
cursor
.
pop
();
if
(
p
==
null
)
{
return
null
;
}
p
=
parents
.
remove
(
parents
.
size
()
-
1
);
index
=
++
p
.
index
;
if
(
index
<
p
.
page
.
getKeyCount
())
{
parents
.
add
(
p
);
Page
x
=
p
.
page
;
x
=
x
.
getChildPage
(
index
);
min
(
x
,
parents
,
null
);
x
=
p
.
page
;
if
(
index
<
x
.
getKeyCount
())
{
cursor
.
push
(
p
);
x
=
x
.
getChildPage
(
index
);
p
=
min
(
x
,
cursor
,
null
);
cursor
.
setCurrentPos
(
p
);
break
;
}
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/store/SpatialKey.java
浏览文件 @
1217a01e
...
...
@@ -6,38 +6,66 @@
*/
package
org
.
h2
.
test
.
store
;
import
java.util.Arrays
;
/**
* A unique spatial key.
*/
public
class
SpatialKey
{
public
float
[]
min
;
public
float
[]
max
;
public
long
id
;
private
float
[]
minMax
;
public
static
SpatialKey
create
(
long
id
,
float
...
minMax
)
{
SpatialKey
k
=
new
SpatialKey
();
k
.
id
=
id
;
int
dimensions
=
minMax
.
length
/
2
;
k
.
min
=
new
float
[
dimensions
];
k
.
max
=
new
float
[
dimensions
];
for
(
int
i
=
0
;
i
<
dimensions
;
i
++)
{
k
.
min
[
i
]
=
minMax
[
i
+
i
];
k
.
max
[
i
]
=
minMax
[
i
+
i
+
1
];
}
return
k
;
/**
* Create a new key.
*
* @param id the id
* @param minMax min x, max x, min y, max y, and so on
*/
public
SpatialKey
(
long
id
,
float
...
minMax
)
{
this
.
id
=
id
;
this
.
minMax
=
minMax
;
}
public
float
min
(
int
dim
)
{
return
minMax
[
dim
+
dim
];
}
public
void
setMin
(
int
dim
,
float
x
)
{
minMax
[
dim
+
dim
]
=
x
;
}
public
float
max
(
int
dim
)
{
return
minMax
[
dim
+
dim
+
1
];
}
public
void
setMax
(
int
dim
,
float
x
)
{
minMax
[
dim
+
dim
+
1
]
=
x
;
}
public
String
toString
()
{
StringBuilder
buff
=
new
StringBuilder
();
buff
.
append
(
id
).
append
(
": ("
);
for
(
int
i
=
0
;
i
<
min
.
length
;
i
++
)
{
for
(
int
i
=
0
;
i
<
min
Max
.
length
;
i
+=
2
)
{
if
(
i
>
0
)
{
buff
.
append
(
", "
);
}
buff
.
append
(
min
[
i
]).
append
(
'/'
).
append
(
max
[
i
]);
buff
.
append
(
min
Max
[
i
]).
append
(
'/'
).
append
(
minMax
[
i
+
1
]);
}
return
buff
.
append
(
")"
).
toString
();
}
public
int
hashCode
()
{
return
(
int
)
((
id
>>>
32
)
^
id
);
}
public
boolean
equals
(
Object
other
)
{
if
(!(
other
instanceof
SpatialKey
))
{
return
false
;
}
SpatialKey
o
=
(
SpatialKey
)
other
;
return
Arrays
.
equals
(
minMax
,
o
.
minMax
);
}
}
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/store/SpatialType.java
浏览文件 @
1217a01e
...
...
@@ -58,15 +58,15 @@ public class SpatialType implements DataType {
SpatialKey
k
=
(
SpatialKey
)
obj
;
int
flags
=
0
;
for
(
int
i
=
0
;
i
<
dimensions
;
i
++)
{
if
(
k
.
min
[
i
]
==
k
.
max
[
i
]
)
{
if
(
k
.
min
(
i
)
==
k
.
max
(
i
)
)
{
flags
|=
1
<<
i
;
}
}
DataUtils
.
writeVarInt
(
buff
,
flags
);
for
(
int
i
=
0
;
i
<
dimensions
;
i
++)
{
buff
.
putFloat
(
k
.
min
[
i
]
);
buff
.
putFloat
(
k
.
min
(
i
)
);
if
((
flags
&
(
1
<<
i
))
==
0
)
{
buff
.
putFloat
(
k
.
max
[
i
]
);
buff
.
putFloat
(
k
.
max
(
i
)
);
}
}
DataUtils
.
writeVarLong
(
buff
,
k
.
id
);
...
...
@@ -74,20 +74,21 @@ public class SpatialType implements DataType {
@Override
public
Object
read
(
ByteBuffer
buff
)
{
SpatialKey
k
=
new
SpatialKey
();
int
flags
=
DataUtils
.
readVarInt
(
buff
);
k
.
min
=
new
float
[
dimensions
];
k
.
max
=
new
float
[
dimensions
];
float
[]
minMax
=
new
float
[
dimensions
*
2
];
for
(
int
i
=
0
;
i
<
dimensions
;
i
++)
{
k
.
min
[
i
]
=
buff
.
getFloat
();
float
min
=
buff
.
getFloat
();
float
max
;
if
((
flags
&
(
1
<<
i
))
!=
0
)
{
k
.
max
[
i
]
=
k
.
min
[
i
]
;
max
=
min
;
}
else
{
k
.
max
[
i
]
=
buff
.
getFloat
();
max
=
buff
.
getFloat
();
}
minMax
[
i
+
i
]
=
min
;
minMax
[
i
+
i
+
1
]
=
max
;
}
k
.
id
=
DataUtils
.
readVarLong
(
buff
);
return
k
;
long
id
=
DataUtils
.
readVarLong
(
buff
);
return
new
SpatialKey
(
id
,
minMax
)
;
}
@Override
...
...
@@ -99,26 +100,19 @@ public class SpatialType implements DataType {
SpatialKey
a
=
(
SpatialKey
)
objA
;
SpatialKey
b
=
(
SpatialKey
)
objB
;
for
(
int
i
=
0
;
i
<
dimensions
;
i
++)
{
if
(
a
.
max
[
i
]
<
b
.
min
[
i
]
||
a
.
min
[
i
]
>
b
.
max
[
i
]
)
{
if
(
a
.
max
(
i
)
<
b
.
min
(
i
)
||
a
.
min
(
i
)
>
b
.
max
(
i
)
)
{
return
false
;
}
}
return
true
;
}
public
SpatialKey
copy
(
SpatialKey
old
)
{
SpatialKey
k
=
new
SpatialKey
();
k
.
min
=
new
float
[
dimensions
];
k
.
max
=
new
float
[
dimensions
];
System
.
arraycopy
(
old
.
min
,
0
,
k
.
min
,
0
,
dimensions
);
System
.
arraycopy
(
old
.
max
,
0
,
k
.
max
,
0
,
dimensions
);
return
k
;
}
public
void
increase
(
SpatialKey
bounds
,
SpatialKey
add
)
{
public
void
increaseBounds
(
Object
bounds
,
Object
add
)
{
SpatialKey
b
=
(
SpatialKey
)
bounds
;
SpatialKey
a
=
(
SpatialKey
)
add
;
for
(
int
i
=
0
;
i
<
dimensions
;
i
++)
{
b
ounds
.
min
[
i
]
=
Math
.
min
(
bounds
.
min
[
i
],
add
.
min
[
i
]
);
b
ounds
.
max
[
i
]
=
Math
.
max
(
bounds
.
max
[
i
],
add
.
max
[
i
]
);
b
.
setMin
(
i
,
Math
.
min
(
b
.
min
(
i
),
a
.
min
(
i
))
);
b
.
setMax
(
i
,
Math
.
max
(
b
.
max
(
i
),
a
.
max
(
i
))
);
}
}
...
...
@@ -134,11 +128,11 @@ public class SpatialType implements DataType {
SpatialKey
b
=
(
SpatialKey
)
objB
;
float
areaOld
=
1
,
areaNew
=
1
;
for
(
int
i
=
0
;
i
<
dimensions
;
i
++)
{
float
min
=
a
.
min
[
i
]
;
float
max
=
a
.
max
[
i
]
;
float
min
=
a
.
min
(
i
)
;
float
max
=
a
.
max
(
i
)
;
areaOld
*=
max
-
min
;
min
=
Math
.
min
(
min
,
b
.
min
[
i
]
);
max
=
Math
.
max
(
max
,
b
.
max
[
i
]
);
min
=
Math
.
min
(
min
,
b
.
min
(
i
)
);
max
=
Math
.
max
(
max
,
b
.
max
(
i
)
);
areaNew
*=
max
-
min
;
}
return
areaNew
-
areaOld
;
...
...
@@ -149,8 +143,8 @@ public class SpatialType implements DataType {
SpatialKey
b
=
(
SpatialKey
)
objB
;
float
area
=
1
;
for
(
int
i
=
0
;
i
<
dimensions
;
i
++)
{
float
min
=
Math
.
min
(
a
.
min
[
i
],
b
.
min
[
i
]
);
float
max
=
Math
.
max
(
a
.
max
[
i
],
b
.
max
[
i
]
);
float
min
=
Math
.
min
(
a
.
min
(
i
),
b
.
min
(
i
)
);
float
max
=
Math
.
max
(
a
.
max
(
i
),
b
.
max
(
i
)
);
area
*=
max
-
min
;
}
return
area
;
...
...
@@ -167,11 +161,40 @@ public class SpatialType implements DataType {
SpatialKey
a
=
(
SpatialKey
)
objA
;
SpatialKey
b
=
(
SpatialKey
)
objB
;
for
(
int
i
=
0
;
i
<
dimensions
;
i
++)
{
if
(
a
.
min
[
i
]
>
b
.
min
[
i
]
||
a
.
max
[
i
]
<
b
.
max
[
i
]
)
{
if
(
a
.
min
(
i
)
>
b
.
min
(
i
)
||
a
.
max
(
i
)
<
b
.
max
(
i
)
)
{
return
false
;
}
}
return
true
;
}
/**
* Check whether a given object is completely inside and does not touch the
* given bound.
*
* @param objA the object to check
* @param objB the bounds
* @return true if a is completely inside b
*/
public
boolean
isInside
(
Object
objA
,
Object
objB
)
{
SpatialKey
a
=
(
SpatialKey
)
objA
;
SpatialKey
b
=
(
SpatialKey
)
objB
;
for
(
int
i
=
0
;
i
<
dimensions
;
i
++)
{
if
(
a
.
min
(
i
)
<=
b
.
min
(
i
)
||
a
.
max
(
i
)
>=
b
.
max
(
i
))
{
return
false
;
}
}
return
true
;
}
public
Object
createBoundingBox
(
Object
objA
)
{
float
[]
minMax
=
new
float
[
dimensions
*
2
];
SpatialKey
a
=
(
SpatialKey
)
objA
;
for
(
int
i
=
0
;
i
<
dimensions
;
i
++)
{
minMax
[
i
+
i
]
=
a
.
min
(
i
);
minMax
[
i
+
i
+
1
]
=
a
.
max
(
i
);
}
return
new
SpatialKey
(
0
,
minMax
);
}
}
This diff is collapsed.
Click to expand it.
h2/src/tools/org/h2/dev/store/btree/BtreeMap.java
浏览文件 @
1217a01e
...
...
@@ -7,7 +7,6 @@
package
org
.
h2
.
dev
.
store
.
btree
;
import
java.util.AbstractSet
;
import
java.util.ArrayList
;
import
java.util.Iterator
;
import
java.util.Set
;
import
java.util.TreeMap
;
...
...
@@ -200,7 +199,7 @@ public class BtreeMap<K, V> {
* @param parents the stack of parent page positions
* @param key the key
*/
protected
void
min
(
Page
p
,
ArrayList
<
CursorPos
>
parents
,
Object
key
)
{
protected
CursorPos
min
(
Page
p
,
Cursor
<
K
,
V
>
cursor
,
Object
key
)
{
while
(
p
!=
null
)
{
if
(!
p
.
isLeaf
())
{
int
x
=
key
==
null
?
-
1
:
p
.
binarySearch
(
key
);
...
...
@@ -212,7 +211,7 @@ public class BtreeMap<K, V> {
CursorPos
c
=
new
CursorPos
();
c
.
page
=
p
;
c
.
index
=
x
;
parents
.
add
(
c
);
cursor
.
push
(
c
);
p
=
p
.
getChildPage
(
x
);
}
else
{
int
x
=
key
==
null
?
0
:
p
.
binarySearch
(
key
);
...
...
@@ -222,10 +221,10 @@ public class BtreeMap<K, V> {
CursorPos
c
=
new
CursorPos
();
c
.
page
=
p
;
c
.
index
=
x
;
parents
.
add
(
c
);
return
;
return
c
;
}
}
return
null
;
}
/**
...
...
@@ -234,29 +233,24 @@ public class BtreeMap<K, V> {
* @param parents the stack of parent page positions
* @return the next key
*/
protected
Object
nextKey
(
ArrayList
<
CursorPos
>
parents
)
{
if
(
parents
.
size
()
==
0
)
{
return
null
;
}
protected
Object
nextKey
(
CursorPos
p
,
Cursor
<
K
,
V
>
cursor
)
{
while
(
true
)
{
// TODO performance: avoid remove/add pairs if possible
CursorPos
p
=
parents
.
remove
(
parents
.
size
()
-
1
);
int
index
=
p
.
index
++;
if
(
index
<
p
.
page
.
getKeyCount
())
{
parents
.
add
(
p
);
return
p
.
page
.
getKey
(
index
);
}
while
(
true
)
{
if
(
parents
.
size
()
==
0
)
{
p
=
cursor
.
pop
();
if
(
p
==
null
)
{
return
null
;
}
p
=
parents
.
remove
(
parents
.
size
()
-
1
);
index
=
++
p
.
index
;
if
(
index
<=
p
.
page
.
getKeyCount
())
{
parents
.
add
(
p
);
cursor
.
push
(
p
);
Page
x
=
p
.
page
;
x
=
x
.
getChildPage
(
index
);
min
(
x
,
parents
,
null
);
x
=
x
.
getChildPage
(
index
);
p
=
min
(
x
,
cursor
,
null
);
cursor
.
setCurrentPos
(
p
);
break
;
}
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/tools/org/h2/dev/store/btree/Cursor.java
浏览文件 @
1217a01e
...
...
@@ -15,16 +15,19 @@ import java.util.Iterator;
* @param <K> the key type
* @param <V> the value type
*/
class
Cursor
<
K
,
V
>
implements
Iterator
<
K
>
{
public
class
Cursor
<
K
,
V
>
implements
Iterator
<
K
>
{
private
final
BtreeMap
<
K
,
V
>
map
;
private
final
ArrayList
<
CursorPos
>
parents
=
new
ArrayList
<
CursorPos
>();
private
CursorPos
currentPos
;
private
K
current
;
Cursor
(
BtreeMap
<
K
,
V
>
map
,
Page
root
,
K
from
)
{
this
.
map
=
map
;
map
.
min
(
root
,
parents
,
from
);
fetchNext
();
currentPos
=
map
.
min
(
root
,
this
,
from
);
if
(
currentPos
!=
null
)
{
fetchNext
();
}
}
public
K
next
()
{
...
...
@@ -37,7 +40,7 @@ class Cursor<K, V> implements Iterator<K> {
@SuppressWarnings
(
"unchecked"
)
private
void
fetchNext
()
{
current
=
(
K
)
map
.
nextKey
(
parent
s
);
current
=
(
K
)
map
.
nextKey
(
currentPos
,
thi
s
);
}
public
boolean
hasNext
()
{
...
...
@@ -48,5 +51,18 @@ class Cursor<K, V> implements Iterator<K> {
throw
new
UnsupportedOperationException
();
}
public
void
setCurrentPos
(
CursorPos
p
)
{
currentPos
=
p
;
}
public
void
push
(
CursorPos
p
)
{
parents
.
add
(
p
);
}
public
CursorPos
pop
()
{
int
size
=
parents
.
size
();
return
size
==
0
?
null
:
parents
.
remove
(
size
-
1
);
}
}
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论