提交 8a96db5a authored 作者: S.Vladykin's avatar S.Vladykin

Batching support for index lookups and batched joins.

上级 b2a70c1c
...@@ -17,7 +17,7 @@ import org.h2.value.ValueNull; ...@@ -17,7 +17,7 @@ import org.h2.value.ValueNull;
* Represents a single SQL statements. * Represents a single SQL statements.
* It wraps a prepared statement. * It wraps a prepared statement.
*/ */
class CommandContainer extends Command { public class CommandContainer extends Command {
private Prepared prepared; private Prepared prepared;
private boolean readOnlyKnown; private boolean readOnlyKnown;
......
...@@ -5,6 +5,10 @@ ...@@ -5,6 +5,10 @@
*/ */
package org.h2.index; package org.h2.index;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Future;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.engine.DbObject; import org.h2.engine.DbObject;
...@@ -424,4 +428,14 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index { ...@@ -424,4 +428,14 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index {
// ignore // ignore
} }
@Override
public int getPreferedLookupBatchSize() {
// No batched lookups supported by default.
return 0;
}
@Override
public List<Future<Cursor>> findBatched(TableFilter filter, List<SearchRow> firstLastPairs) {
throw DbException.throwInternalError("Must not be called if getPreferedLookupBatchSize() is 0.");
}
} }
...@@ -5,6 +5,9 @@ ...@@ -5,6 +5,9 @@
*/ */
package org.h2.index; package org.h2.index;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Future;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.result.SearchRow; import org.h2.result.SearchRow;
...@@ -256,4 +259,28 @@ public interface Index extends SchemaObject { ...@@ -256,4 +259,28 @@ public interface Index extends SchemaObject {
*/ */
void setSortedInsertMode(boolean sortedInsertMode); void setSortedInsertMode(boolean sortedInsertMode);
/**
* If this index can do batched lookups, it may return it's preferred batch size,
* otherwise it must return 0.
*
* @return preferred batch size or 0 if lookup batching is not supported
* @see #findBatched(TableFilter, Collection)
*/
int getPreferedLookupBatchSize();
/**
* Do batched lookup over the given collection of {@link SearchRow} pairs as in
* {@link #find(TableFilter, SearchRow, SearchRow)}.
* <br/><br/>
* Correct implementation must always return number of future cursors equal to
* {@code firstLastPairs.size() / 2}. Instead of {@link Future} containing empty
* {@link Cursor} it is possible to put {@code null} in result list.
*
* @param filter the table filter
* @param firstLastPairs List of batched search row pairs as in
* {@link #find(TableFilter, SearchRow, SearchRow)}, the collection will be reused by H2,
* thus it makes sense to defensively copy contents if needed.
* @return batched cursors for respective search row pairs in the same order
*/
List<Future<Cursor>> findBatched(TableFilter filter, List<SearchRow> firstLastPairs);
} }
...@@ -68,12 +68,12 @@ public class IndexCursor implements Cursor { ...@@ -68,12 +68,12 @@ public class IndexCursor implements Cursor {
} }
/** /**
* Re-evaluate the start and end values of the index search for rows. * Prepare this index cursor to make a lookup in index.
* *
* @param s the session * @param s Session.
* @param indexConditions the index conditions * @param indexConditions Index conditions.
*/ */
public void find(Session s, ArrayList<IndexCondition> indexConditions) { public void prepare(Session s, ArrayList<IndexCondition> indexConditions) {
this.session = s; this.session = s;
alwaysFalse = false; alwaysFalse = false;
start = end = null; start = end = null;
...@@ -148,6 +148,16 @@ public class IndexCursor implements Cursor { ...@@ -148,6 +148,16 @@ public class IndexCursor implements Cursor {
} }
} }
} }
}
/**
* Re-evaluate the start and end values of the index search for rows.
*
* @param s the session
* @param indexConditions the index conditions
*/
public void find(Session s, ArrayList<IndexCondition> indexConditions) {
prepare(s, indexConditions);
if (inColumn != null) { if (inColumn != null) {
return; return;
} }
...@@ -252,6 +262,24 @@ public class IndexCursor implements Cursor { ...@@ -252,6 +262,24 @@ public class IndexCursor implements Cursor {
return alwaysFalse; return alwaysFalse;
} }
/**
* Get start search row.
*
* @return search row
*/
public SearchRow getStart() {
return start;
}
/**
* Get end search row.
*
* @return search row
*/
public SearchRow getEnd() {
return end;
}
@Override @Override
public Row get() { public Row get() {
if (cursor == null) { if (cursor == null) {
......
...@@ -6,7 +6,10 @@ ...@@ -6,7 +6,10 @@
package org.h2.index; package org.h2.index;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Future;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.engine.Database; import org.h2.engine.Database;
import org.h2.engine.DbObject; import org.h2.engine.DbObject;
...@@ -387,4 +390,13 @@ public class MultiVersionIndex implements Index { ...@@ -387,4 +390,13 @@ public class MultiVersionIndex implements Index {
delta.setSortedInsertMode(sortedInsertMode); delta.setSortedInsertMode(sortedInsertMode);
} }
@Override
public int getPreferedLookupBatchSize() {
return 0;
}
@Override
public List<Future<Cursor>> findBatched(TableFilter filter, List<SearchRow> firstLastPairs) {
throw DbException.throwInternalError("Must never be called.");
}
} }
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
package org.h2.table; package org.h2.table;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
...@@ -104,7 +105,7 @@ public abstract class Table extends SchemaObjectBase { ...@@ -104,7 +105,7 @@ public abstract class Table extends SchemaObjectBase {
private ArrayList<TableView> views; private ArrayList<TableView> views;
private boolean checkForeignKeyConstraints = true; private boolean checkForeignKeyConstraints = true;
private boolean onCommitDrop, onCommitTruncate; private boolean onCommitDrop, onCommitTruncate;
private Row nullRow; private volatile Row nullRow;
public Table(Schema schema, int id, String name, boolean persistIndexes, public Table(Schema schema, int id, String name, boolean persistIndexes,
boolean persistData) { boolean persistData) {
...@@ -616,14 +617,15 @@ public abstract class Table extends SchemaObjectBase { ...@@ -616,14 +617,15 @@ public abstract class Table extends SchemaObjectBase {
return new SimpleRow(new Value[columns.length]); return new SimpleRow(new Value[columns.length]);
} }
synchronized Row getNullRow() { Row getNullRow() {
if (nullRow == null) { Row row = nullRow;
nullRow = new Row(new Value[columns.length], 1); if (row == null) {
for (int i = 0; i < columns.length; i++) { // Here can be concurrently produced more than one row, but it must be ok.
nullRow.setValue(i, ValueNull.INSTANCE); Value[] values = new Value[columns.length];
} Arrays.fill(values, ValueNull.INSTANCE);
nullRow = row = new Row(values, 1);
} }
return nullRow; return row;
} }
public Column[] getColumns() { public Column[] getColumns() {
......
/*
* Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.util;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
* Future which is already done.
*
* @param <T> Result value.
* @author Sergi Vladykin
*/
public class DoneFuture<T> implements Future<T> {
final T x;
public DoneFuture(T x) {
this.x = x;
}
@Override
public T get() throws InterruptedException, ExecutionException {
return x;
}
@Override
public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
return x;
}
@Override
public boolean isDone() {
return true;
}
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
return false;
}
@Override
public boolean isCancelled() {
return false;
}
@Override
public String toString() {
return "DoneFuture->" + x;
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论