Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
1217a01e
提交
1217a01e
authored
8月 27, 2012
作者:
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
;
}
}
...
...
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
);
}
}
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
);
}
}
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
;
}
}
...
...
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
);
}
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论