Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
3b15a771
提交
3b15a771
authored
11月 21, 2015
作者:
S.Vladykin
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
wip
上级
8f467f15
隐藏空白字符变更
内嵌
并排
正在显示
2 个修改的文件
包含
215 行增加
和
67 行删除
+215
-67
JoinBatch.java
h2/src/main/org/h2/table/JoinBatch.java
+214
-66
LazyFuture.java
h2/src/main/org/h2/util/LazyFuture.java
+1
-1
没有找到文件。
h2/src/main/org/h2/table/JoinBatch.java
浏览文件 @
3b15a771
...
...
@@ -64,7 +64,7 @@ public final class JoinBatch {
}
};
private
ViewIndexLookupBatch
viewIndexLookupBatch
;
private
boolean
batchedSubQuery
;
private
Future
<
Cursor
>
viewTopFutureCursor
;
private
JoinFilter
[]
filters
;
...
...
@@ -112,7 +112,7 @@ public final class JoinBatch {
public
IndexLookupBatch
getLookupBatch
(
int
joinFilterId
)
{
return
filters
[
joinFilterId
].
lookupBatch
;
}
/**
* Reset state of this batch.
*/
...
...
@@ -163,7 +163,7 @@ public final class JoinBatch {
current
=
new
JoinRow
(
new
Object
[
filters
.
length
]);
// initialize top cursor
Cursor
cursor
;
if
(
viewIndexLookupBatch
==
null
)
{
if
(
!
batchedSubQuery
)
{
// it is a top level batched query
TableFilter
f
=
top
.
filter
;
IndexCursor
indexCursor
=
f
.
getIndexCursor
();
...
...
@@ -372,16 +372,22 @@ public final class JoinBatch {
* @return Adapter to allow joining to this batch in sub-queries and views.
*/
private
IndexLookupBatch
viewIndexLookupBatch
(
ViewIndex
viewIndex
)
{
assert
viewIndexLookupBatch
==
null
;
return
viewIndexLookupBatch
=
new
ViewIndexLookupBatch
(
viewIndex
);
assert
!
batchedSubQuery
;
batchedSubQuery
=
true
;
return
new
ViewIndexLookupBatch
(
viewIndex
);
}
/**
* Create index lookup batch for a view index.
*
* @param viewIndex view index
* @return index lookup batch or {@code null} if batching is not supported for this query
*/
public
static
IndexLookupBatch
createViewIndexLookupBatch
(
ViewIndex
viewIndex
)
{
Query
query
=
viewIndex
.
getQuery
();
if
(
query
.
isUnion
())
{
SelectUnion
union
=
(
SelectUnion
)
query
;
// TODO
return
null
;
ViewIndexLookupBatchUnion
unionBatch
=
new
ViewIndexLookupBatchUnion
(
viewIndex
);
return
unionBatch
.
initialize
()
?
unionBatch
:
null
;
}
else
{
Select
select
=
(
Select
)
query
;
// here we have already prepared plan for our sub-query,
...
...
@@ -649,10 +655,7 @@ public final class JoinBatch {
private
final
List
<
Future
<
Cursor
>>
result
=
new
SingletonList
<
Future
<
Cursor
>>();
/**
* @param index Index.
*/
public
FakeLookupBatch
(
TableFilter
filter
)
{
private
FakeLookupBatch
(
TableFilter
filter
)
{
this
.
filter
=
filter
;
}
...
...
@@ -716,22 +719,28 @@ public final class JoinBatch {
}
/**
*
Index lookup batch over this join batch for a sub-query or view
.
*
Base class for SELECT and SELECT UNION view index lookup batches
.
*/
private
final
class
ViewIndexLookupBatch
implements
IndexLookupBatch
{
pr
ivate
final
ViewIndex
viewIndex
;
pr
ivate
final
ArrayList
<
Future
<
Cursor
>>
result
=
New
.
arrayList
();
pr
ivate
int
resultSize
;
pr
ivate
ViewIndexLookupBatch
(
ViewIndex
viewIndex
)
{
private
abstract
static
class
ViewIndexLookupBatchBase
implements
IndexLookupBatch
{
pr
otected
final
ViewIndex
viewIndex
;
pr
otected
final
ArrayList
<
Future
<
Cursor
>>
result
=
New
.
arrayList
();
pr
otected
int
resultSize
;
pr
otected
ViewIndexLookupBatchBase
(
ViewIndex
viewIndex
)
{
this
.
viewIndex
=
viewIndex
;
}
private
boolean
resetAfterFind
()
{
protected
abstract
boolean
collectSearchRows
();
protected
abstract
QueryRunnerBase
newQueryRunner
();
protected
abstract
void
startQueryRunners
();
protected
final
boolean
resetAfterFind
()
{
if
(
resultSize
<
0
)
{
// method find was called, we need to reset futures to initial state for reuse
for
(
int
i
=
0
,
size
=
-
resultSize
;
i
<
size
;
i
++)
{
((
QueryRunner
)
result
.
get
(
i
)).
reset
();
((
QueryRunner
Base
)
result
.
get
(
i
)).
reset
();
}
resultSize
=
0
;
return
true
;
...
...
@@ -740,25 +749,101 @@ public final class JoinBatch {
}
@Override
public
boolean
addSearchRows
(
SearchRow
first
,
SearchRow
last
)
{
public
final
boolean
addSearchRows
(
SearchRow
first
,
SearchRow
last
)
{
resetAfterFind
();
viewIndex
.
setupQueryParameters
(
viewIndex
.
getSession
(),
first
,
last
,
null
);
if
(!
top
.
collectSearchRows
())
{
if
(!
collectSearchRows
())
{
return
false
;
}
QueryRunner
r
;
QueryRunner
Base
r
;
if
(
resultSize
<
result
.
size
())
{
// get reused runner
r
=
(
QueryRunner
)
result
.
get
(
resultSize
);
r
=
(
QueryRunner
Base
)
result
.
get
(
resultSize
);
}
else
{
// create new runner
result
.
add
(
r
=
new
QueryRunner
());
result
.
add
(
r
=
newQueryRunner
());
}
r
.
first
=
first
;
r
.
last
=
last
;
resultSize
++;
return
true
;
}
@Override
public
void
reset
()
{
if
(
resultSize
!=
0
&&
!
resetAfterFind
())
{
// find was not called, need to just clear runners
for
(
int
i
=
0
;
i
<
resultSize
;
i
++)
{
((
QueryRunnerBase
)
result
.
get
(
i
)).
clear
();
}
resultSize
=
0
;
}
}
@Override
public
final
List
<
Future
<
Cursor
>>
find
()
{
if
(
resultSize
==
0
)
{
return
Collections
.
emptyList
();
}
startQueryRunners
();
List
<
Future
<
Cursor
>>
list
=
resultSize
==
result
.
size
()
?
result
:
result
.
subList
(
0
,
resultSize
);
// mark that method find was called
resultSize
=
-
resultSize
;
return
list
;
}
}
/**
* Lazy query runner base.
*/
private
abstract
static
class
QueryRunnerBase
extends
LazyFuture
<
Cursor
>
{
protected
final
ViewIndex
viewIndex
;
protected
SearchRow
first
;
protected
SearchRow
last
;
public
QueryRunnerBase
(
ViewIndex
viewIndex
)
{
this
.
viewIndex
=
viewIndex
;
}
protected
void
clear
()
{
first
=
last
=
null
;
}
@Override
public
final
boolean
reset
()
{
if
(
super
.
reset
())
{
return
true
;
}
// this query runner was never executed, need to clear manually
clear
();
return
false
;
}
protected
final
ViewCursor
newCursor
(
LocalResult
localResult
)
{
ViewCursor
cursor
=
new
ViewCursor
(
viewIndex
,
localResult
,
first
,
last
);
clear
();
return
cursor
;
}
}
/**
* View index lookup batch for a simple SELECT.
*/
private
final
class
ViewIndexLookupBatch
extends
ViewIndexLookupBatchBase
{
private
ViewIndexLookupBatch
(
ViewIndex
viewIndex
)
{
super
(
viewIndex
);
}
@Override
protected
QueryRunnerBase
newQueryRunner
()
{
return
new
QueryRunner
(
viewIndex
);
}
@Override
protected
boolean
collectSearchRows
()
{
return
top
.
collectSearchRows
();
}
@Override
public
boolean
isBatchFull
()
{
...
...
@@ -766,10 +851,13 @@ public final class JoinBatch {
}
@Override
public
List
<
Future
<
Cursor
>>
find
()
{
if
(
resultSize
==
0
)
{
return
Collections
.
emptyList
();
}
public
void
reset
()
{
super
.
reset
();
JoinBatch
.
this
.
reset
();
}
@Override
protected
void
startQueryRunners
()
{
// we do batched find only for top table filter and then lazily run the ViewIndex query
// for each received top future cursor
List
<
Future
<
Cursor
>>
topFutureCursors
=
top
.
find
();
...
...
@@ -781,48 +869,23 @@ public final class JoinBatch {
QueryRunner
r
=
(
QueryRunner
)
result
.
get
(
i
);
r
.
topFutureCursor
=
topFutureCursors
.
get
(
i
);
}
List
<
Future
<
Cursor
>>
list
=
resultSize
==
result
.
size
()
?
result
:
result
.
subList
(
0
,
resultSize
);
// mark that method find was called
resultSize
=
-
resultSize
;
return
list
;
}
@Override
public
void
reset
()
{
if
(
resultSize
!=
0
&&
!
resetAfterFind
())
{
// find was not called, need to just clear runners
for
(
int
i
=
0
;
i
<
resultSize
;
i
++)
{
((
QueryRunner
)
result
.
get
(
i
)).
clear
();
}
resultSize
=
0
;
}
JoinBatch
.
this
.
reset
();
}
/**
*
Lazy q
uery runner.
*
Q
uery runner.
*/
private
class
QueryRunner
extends
LazyFuture
<
Cursor
>
{
private
final
class
QueryRunner
extends
QueryRunnerBase
{
private
Future
<
Cursor
>
topFutureCursor
;
private
SearchRow
first
;
private
SearchRow
last
;
private
void
clear
()
{
topFutureCursor
=
null
;
first
=
last
=
null
;
public
QueryRunner
(
ViewIndex
viewIndex
)
{
super
(
viewIndex
);
}
@Override
public
boolean
reset
()
{
if
(
super
.
reset
())
{
return
true
;
}
// this query runner was never executed, need to clear manually
clear
();
return
false
;
protected
void
clear
()
{
topFutureCursor
=
null
;
super
.
clear
();
}
@Override
protected
Cursor
run
()
throws
Exception
{
if
(
topFutureCursor
==
null
)
{
...
...
@@ -836,9 +899,94 @@ public final class JoinBatch {
}
finally
{
JoinBatch
.
this
.
viewTopFutureCursor
=
null
;
}
ViewCursor
cursor
=
new
ViewCursor
(
viewIndex
,
localResult
,
first
,
last
);
clear
();
return
cursor
;
return
newCursor
(
localResult
);
}
}
}
/**
* View index lookup batch for UNION queries.
*/
private
static
final
class
ViewIndexLookupBatchUnion
extends
ViewIndexLookupBatchBase
{
private
ArrayList
<
JoinFilter
>
tops
=
New
.
arrayList
();
private
ArrayList
<
JoinBatch
>
joinBatches
=
New
.
arrayList
();
protected
ViewIndexLookupBatchUnion
(
ViewIndex
viewIndex
)
{
super
(
viewIndex
);
}
/**
* @return {@code true} if initialized successfully
*/
private
boolean
initialize
()
{
return
collectTopTableFilters
(
viewIndex
.
getQuery
());
}
private
boolean
collectTopTableFilters
(
Query
query
)
{
if
(
query
.
isUnion
())
{
SelectUnion
union
=
(
SelectUnion
)
query
;
return
collectTopTableFilters
(
union
.
getLeft
())
&&
collectTopTableFilters
(
union
.
getRight
());
}
Select
select
=
(
Select
)
query
;
JoinBatch
jb
=
select
.
getJoinBatch
();
if
(
jb
==
null
)
{
// if we've found non-batched select then we can't do batching at all here
return
false
;
}
tops
.
add
(
jb
.
filters
[
0
]);
return
true
;
}
@Override
public
boolean
isBatchFull
()
{
// if at least one is full
for
(
int
i
=
0
;
i
<
tops
.
size
();
i
++)
{
if
(
tops
.
get
(
i
).
isBatchFull
())
{
return
true
;
}
}
return
false
;
}
@Override
protected
boolean
collectSearchRows
()
{
for
(
int
i
=
0
;
i
<
tops
.
size
();
i
++)
{
if
(
tops
.
get
(
i
).
collectSearchRows
())
{
// TODO
}
}
return
true
;
}
@Override
protected
QueryRunnerBase
newQueryRunner
()
{
return
new
QueryRunnerUnion
();
}
@Override
protected
void
startQueryRunners
()
{
// TODO Auto-generated method stub
}
/**
* Query runner for UNION.
*/
private
class
QueryRunnerUnion
extends
QueryRunnerBase
{
public
QueryRunnerUnion
()
{
super
(
ViewIndexLookupBatchUnion
.
this
.
viewIndex
);
}
@Override
protected
void
clear
()
{
super
.
clear
();
// TODO
}
@Override
protected
Cursor
run
()
throws
Exception
{
// TODO Auto-generated method stub
return
null
;
}
}
}
...
...
h2/src/main/org/h2/util/LazyFuture.java
浏览文件 @
3b15a771
...
...
@@ -101,6 +101,6 @@ public abstract class LazyFuture<T> implements Future<T> {
@Override
public
boolean
isDone
()
{
return
state
==
S_DONE
;
return
state
!=
S_READY
;
}
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论