提交 69f3867b authored 作者: S.Vladykin's avatar S.Vladykin

ready

上级 cb74fee7
...@@ -64,6 +64,8 @@ public final class JoinBatch { ...@@ -64,6 +64,8 @@ public final class JoinBatch {
} }
}; };
private static final Future<Cursor> EMPTY_FUTURE_CURSOR = new DoneFuture<Cursor>(EMPTY_CURSOR);
private boolean batchedSubQuery; private boolean batchedSubQuery;
private Future<Cursor> viewTopFutureCursor; private Future<Cursor> viewTopFutureCursor;
...@@ -164,7 +166,6 @@ public final class JoinBatch { ...@@ -164,7 +166,6 @@ public final class JoinBatch {
// initialize top cursor // initialize top cursor
Cursor cursor; Cursor cursor;
if (batchedSubQuery) { if (batchedSubQuery) {
// we are at the batched sub-query
assert viewTopFutureCursor != null; assert viewTopFutureCursor != null;
cursor = get(viewTopFutureCursor); cursor = get(viewTopFutureCursor);
} else { } else {
...@@ -313,7 +314,7 @@ public final class JoinBatch { ...@@ -313,7 +314,7 @@ public final class JoinBatch {
if (newCursor) { if (newCursor) {
if (jfId == 0) { if (jfId == 0) {
// the top cursor is new and empty, drop it // the top cursor is new and empty, then the whole select will not produce any rows
current.drop(); current.drop();
return; return;
} }
...@@ -385,7 +386,8 @@ public final class JoinBatch { ...@@ -385,7 +386,8 @@ public final class JoinBatch {
Query query = viewIndex.getQuery(); Query query = viewIndex.getQuery();
query.prepareJoinBatch(); query.prepareJoinBatch();
if (query.isUnion()) { if (query.isUnion()) {
return new ViewIndexLookupBatchUnion(viewIndex); ViewIndexLookupBatchUnion unionBatch = new ViewIndexLookupBatchUnion(viewIndex);
return unionBatch.hasBatchedQueries() ? unionBatch : null;
} }
JoinBatch jb = ((Select) query).getJoinBatch(); JoinBatch jb = ((Select) query).getJoinBatch();
if (jb == null) { if (jb == null) {
...@@ -717,7 +719,8 @@ public final class JoinBatch { ...@@ -717,7 +719,8 @@ public final class JoinBatch {
/** /**
* Base class for SELECT and SELECT UNION view index lookup batches. * Base class for SELECT and SELECT UNION view index lookup batches.
*/ */
private abstract static class ViewIndexLookupBatchBase implements IndexLookupBatch { private abstract static class ViewIndexLookupBatchBase<R extends QueryRunnerBase>
implements IndexLookupBatch {
protected final ViewIndex viewIndex; protected final ViewIndex viewIndex;
protected final ArrayList<Future<Cursor>> result = New.arrayList(); protected final ArrayList<Future<Cursor>> result = New.arrayList();
protected int resultSize; protected int resultSize;
...@@ -726,9 +729,9 @@ public final class JoinBatch { ...@@ -726,9 +729,9 @@ public final class JoinBatch {
this.viewIndex = viewIndex; this.viewIndex = viewIndex;
} }
protected abstract boolean collectSearchRows(); protected abstract boolean collectSearchRows(R r);
protected abstract QueryRunnerBase newQueryRunner(); protected abstract R newQueryRunner();
protected abstract void startQueryRunners(); protected abstract void startQueryRunners();
...@@ -736,7 +739,7 @@ public final class JoinBatch { ...@@ -736,7 +739,7 @@ public final class JoinBatch {
if (resultSize < 0) { if (resultSize < 0) {
// method find was called, we need to reset futures to initial state for reuse // method find was called, we need to reset futures to initial state for reuse
for (int i = 0, size = -resultSize; i < size; i++) { for (int i = 0, size = -resultSize; i < size; i++) {
((QueryRunnerBase) result.get(i)).reset(); queryRunner(i).reset();
} }
resultSize = 0; resultSize = 0;
return true; return true;
...@@ -744,23 +747,29 @@ public final class JoinBatch { ...@@ -744,23 +747,29 @@ public final class JoinBatch {
return false; return false;
} }
@SuppressWarnings("unchecked")
protected R queryRunner(int i) {
return (R) result.get(i);
}
@Override @Override
public final boolean addSearchRows(SearchRow first, SearchRow last) { public final boolean addSearchRows(SearchRow first, SearchRow last) {
resetAfterFind(); resetAfterFind();
viewIndex.setupQueryParameters(viewIndex.getSession(), first, last, null); viewIndex.setupQueryParameters(viewIndex.getSession(), first, last, null);
if (!collectSearchRows()) { R r;
return false;
}
QueryRunnerBase r;
if (resultSize < result.size()) { if (resultSize < result.size()) {
// get reused runner // get reused runner
r = (QueryRunnerBase) result.get(resultSize); r = queryRunner(resultSize);
} else { } else {
// create new runner // create new runner
result.add(r = newQueryRunner()); result.add(r = newQueryRunner());
} }
r.first = first; r.first = first;
r.last = last; r.last = last;
if (!collectSearchRows(r)) {
r.clear();
return false;
}
resultSize++; resultSize++;
return true; return true;
} }
...@@ -826,23 +835,24 @@ public final class JoinBatch { ...@@ -826,23 +835,24 @@ public final class JoinBatch {
/** /**
* View index lookup batch for a simple SELECT. * View index lookup batch for a simple SELECT.
*/ */
private final class ViewIndexLookupBatch extends ViewIndexLookupBatchBase { private final class ViewIndexLookupBatch extends ViewIndexLookupBatchBase<QueryRunner> {
private ViewIndexLookupBatch(ViewIndex viewIndex) { private ViewIndexLookupBatch(ViewIndex viewIndex) {
super(viewIndex); super(viewIndex);
} }
@Override @Override
protected QueryRunnerBase newQueryRunner() { protected QueryRunner newQueryRunner() {
return new QueryRunner(viewIndex); return new QueryRunner(viewIndex);
} }
@Override @Override
protected boolean collectSearchRows() { protected boolean collectSearchRows(QueryRunner r) {
return top.collectSearchRows(); return top.collectSearchRows();
} }
@Override @Override
public boolean isBatchFull() { public boolean isBatchFull() {
assert resultSize >= 0;
return top.isBatchFull(); return top.isBatchFull();
} }
...@@ -856,10 +866,11 @@ public final class JoinBatch { ...@@ -856,10 +866,11 @@ public final class JoinBatch {
", expected :" + resultSize); ", expected :" + resultSize);
} }
for (int i = 0; i < resultSize; i++) { for (int i = 0; i < resultSize; i++) {
QueryRunner r = (QueryRunner) result.get(i); QueryRunner r = queryRunner(i);
r.topFutureCursor = topFutureCursors.get(i); r.topFutureCursor = topFutureCursors.get(i);
} }
} }
}
/** /**
* Query runner. * Query runner.
...@@ -872,8 +883,8 @@ public final class JoinBatch { ...@@ -872,8 +883,8 @@ public final class JoinBatch {
} }
protected void clear() { protected void clear() {
topFutureCursor = null;
super.clear(); super.clear();
topFutureCursor = null;
} }
@Override @Override
...@@ -882,6 +893,7 @@ public final class JoinBatch { ...@@ -882,6 +893,7 @@ public final class JoinBatch {
// if the top cursor is empty then the whole query will produce empty result // if the top cursor is empty then the whole query will produce empty result
return EMPTY_CURSOR; return EMPTY_CURSOR;
} }
viewIndex.setupQueryParameters(viewIndex.getSession(), first, last, null);
JoinBatch.this.viewTopFutureCursor = topFutureCursor; JoinBatch.this.viewTopFutureCursor = topFutureCursor;
LocalResult localResult; LocalResult localResult;
try { try {
...@@ -892,42 +904,53 @@ public final class JoinBatch { ...@@ -892,42 +904,53 @@ public final class JoinBatch {
return newCursor(localResult); return newCursor(localResult);
} }
} }
}
/** /**
* View index lookup batch for UNION queries. * View index lookup batch for UNION queries.
*/ */
private static final class ViewIndexLookupBatchUnion extends ViewIndexLookupBatchBase { private static final class ViewIndexLookupBatchUnion
private ArrayList<JoinFilter> tops = New.arrayList(); extends ViewIndexLookupBatchBase<QueryRunnerUnion> {
private ArrayList<JoinBatch> joinBatches = New.arrayList(); private ArrayList<JoinFilter> filters;
private ArrayList<JoinBatch> joinBatches;
private boolean onlyBatchedQueries = true;
protected ViewIndexLookupBatchUnion(ViewIndex viewIndex) { protected ViewIndexLookupBatchUnion(ViewIndex viewIndex) {
super(viewIndex); super(viewIndex);
collectTopTableFilters(viewIndex.getQuery()); collectJoinBatches(viewIndex.getQuery());
}
private boolean hasBatchedQueries() {
return joinBatches != null;
} }
private void collectTopTableFilters(Query query) { private void collectJoinBatches(Query query) {
if (query.isUnion()) { if (query.isUnion()) {
SelectUnion union = (SelectUnion) query; SelectUnion union = (SelectUnion) query;
collectTopTableFilters(union.getLeft()); collectJoinBatches(union.getLeft());
collectTopTableFilters(union.getRight()); collectJoinBatches(union.getRight());
} else { } else {
Select select = (Select) query; Select select = (Select) query;
JoinBatch jb = select.getJoinBatch(); JoinBatch jb = select.getJoinBatch();
if (jb == null) { if (jb == null) {
// TODO need some wrapper for a non-batched query onlyBatchedQueries = false;
} } else {
assert !jb.batchedSubQuery; assert !jb.batchedSubQuery;
jb.batchedSubQuery = true; jb.batchedSubQuery = true;
tops.add(jb.filters[0]); if (joinBatches == null) {
joinBatches = New.arrayList();
filters = New.arrayList();
}
filters.add(jb.filters[0]);
joinBatches.add(jb);
}
} }
} }
@Override @Override
public boolean isBatchFull() { public boolean isBatchFull() {
// if at least one is full // if at least one is full
for (int i = 0; i < tops.size(); i++) { for (int i = 0; i < filters.size(); i++) {
if (tops.get(i).isBatchFull()) { if (filters.get(i).isBatchFull()) {
return true; return true;
} }
} }
...@@ -935,44 +958,76 @@ public final class JoinBatch { ...@@ -935,44 +958,76 @@ public final class JoinBatch {
} }
@Override @Override
protected boolean collectSearchRows() { protected boolean collectSearchRows(QueryRunnerUnion r) {
for (int i = 0; i < tops.size(); i++) { boolean collected = false;
if (tops.get(i).collectSearchRows()) { for (int i = 0; i < filters.size(); i++) {
// TODO if (filters.get(i).collectSearchRows()) {
collected = true;
} else {
r.topFutureCursors[i] = EMPTY_FUTURE_CURSOR;
} }
} }
return true; return collected || !onlyBatchedQueries;
} }
@Override @Override
protected QueryRunnerBase newQueryRunner() { protected QueryRunnerUnion newQueryRunner() {
return new QueryRunnerUnion(); return new QueryRunnerUnion(this);
} }
@Override @Override
protected void startQueryRunners() { protected void startQueryRunners() {
// TODO Auto-generated method stub for (int i = 0; i < filters.size(); i++) {
List<Future<Cursor>> topFutureCursors = filters.get(i).find();
for (int j = 0, k = 0; j < resultSize; j++) {
Future<Cursor>[] cs = queryRunner(j).topFutureCursors;
if (cs[j] == null) {
cs[j] = topFutureCursors.get(k++);
}
}
}
}
} }
/** /**
* Query runner for UNION. * Query runner for UNION.
*/ */
private class QueryRunnerUnion extends QueryRunnerBase { private static class QueryRunnerUnion extends QueryRunnerBase {
public QueryRunnerUnion() { private ViewIndexLookupBatchUnion batchUnion;
super(ViewIndexLookupBatchUnion.this.viewIndex); private Future<Cursor>[] topFutureCursors;
@SuppressWarnings("unchecked")
public QueryRunnerUnion(ViewIndexLookupBatchUnion batchUnion) {
super(batchUnion.viewIndex);
this.batchUnion = batchUnion;
topFutureCursors = new Future[batchUnion.filters.size()];
} }
@Override @Override
protected void clear() { protected void clear() {
super.clear(); super.clear();
// TODO for (int i = 0; i < topFutureCursors.length; i++) {
topFutureCursors[i] = null;
}
} }
@Override @Override
protected Cursor run() throws Exception { protected Cursor run() throws Exception {
// TODO Auto-generated method stub viewIndex.setupQueryParameters(viewIndex.getSession(), first, last, null);
return null; ArrayList<JoinBatch> joinBatches = batchUnion.joinBatches;
for (int i = 0, size = joinBatches.size(); i < size; i++) {
assert topFutureCursors[i] != null;
joinBatches.get(i).viewTopFutureCursor = topFutureCursors[i];
} }
LocalResult localResult;
try {
localResult = viewIndex.getQuery().query(0);
} finally {
for (int i = 0, size = joinBatches.size(); i < size; i++) {
joinBatches.get(i).viewTopFutureCursor = null;
}
}
return newCursor(localResult);
} }
} }
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论