提交 4ccf2510 authored 作者: andrei's avatar andrei

issue_435

上级 5b6bf351
...@@ -197,7 +197,7 @@ public class MVPrimaryIndex extends BaseIndex { ...@@ -197,7 +197,7 @@ public class MVPrimaryIndex extends BaseIndex {
} }
} }
TransactionMap<Value, Value> map = getMap(session); TransactionMap<Value, Value> map = getMap(session);
return new MVStoreCursor(session, map.entryIterator(min), max); return new MVStoreCursor(session, map.entryIterator(min, max));
} }
@Override @Override
...@@ -270,13 +270,13 @@ public class MVPrimaryIndex extends BaseIndex { ...@@ -270,13 +270,13 @@ public class MVPrimaryIndex extends BaseIndex {
TransactionMap<Value, Value> map = getMap(session); TransactionMap<Value, Value> map = getMap(session);
ValueLong v = (ValueLong) (first ? map.firstKey() : map.lastKey()); ValueLong v = (ValueLong) (first ? map.firstKey() : map.lastKey());
if (v == null) { if (v == null) {
return new MVStoreCursor(session, Collections return new MVStoreCursor(session,
.<Entry<Value, Value>> emptyList().iterator(), null); Collections.<Entry<Value, Value>> emptyList().iterator());
} }
Value value = map.get(v); Value value = map.get(v);
Entry<Value, Value> e = new DataUtils.MapEntry<Value, Value>(v, value); Entry<Value, Value> e = new DataUtils.MapEntry<Value, Value>(v, value);
List<Entry<Value, Value>> list = Arrays.asList(e); List<Entry<Value, Value>> list = Collections.singletonList(e);
MVStoreCursor c = new MVStoreCursor(session, list.iterator(), v); MVStoreCursor c = new MVStoreCursor(session, list.iterator());
c.next(); c.next();
return c; return c;
} }
...@@ -356,7 +356,7 @@ public class MVPrimaryIndex extends BaseIndex { ...@@ -356,7 +356,7 @@ public class MVPrimaryIndex extends BaseIndex {
*/ */
Cursor find(Session session, ValueLong first, ValueLong last) { Cursor find(Session session, ValueLong first, ValueLong last) {
TransactionMap<Value, Value> map = getMap(session); TransactionMap<Value, Value> map = getMap(session);
return new MVStoreCursor(session, map.entryIterator(first), last); return new MVStoreCursor(session, map.entryIterator(first, last));
} }
@Override @Override
...@@ -385,14 +385,12 @@ public class MVPrimaryIndex extends BaseIndex { ...@@ -385,14 +385,12 @@ public class MVPrimaryIndex extends BaseIndex {
private final Session session; private final Session session;
private final Iterator<Entry<Value, Value>> it; private final Iterator<Entry<Value, Value>> it;
private final ValueLong last;
private Entry<Value, Value> current; private Entry<Value, Value> current;
private Row row; private Row row;
public MVStoreCursor(Session session, Iterator<Entry<Value, Value>> it, ValueLong last) { public MVStoreCursor(Session session, Iterator<Entry<Value, Value>> it) {
this.session = session; this.session = session;
this.it = it; this.it = it;
this.last = last;
} }
@Override @Override
...@@ -415,9 +413,6 @@ public class MVPrimaryIndex extends BaseIndex { ...@@ -415,9 +413,6 @@ public class MVPrimaryIndex extends BaseIndex {
@Override @Override
public boolean next() { public boolean next() {
current = it.hasNext() ? it.next() : null; current = it.hasNext() ? it.next() : null;
if (current != null && current.getKey().getLong() > last.getLong()) {
current = null;
}
row = null; row = null;
return current != null; return current != null;
} }
......
...@@ -1470,7 +1470,7 @@ public class TransactionStore { ...@@ -1470,7 +1470,7 @@ public class TransactionStore {
* @param from the first key to return * @param from the first key to return
* @return the iterator * @return the iterator
*/ */
public Iterator<Entry<K, V>> entryIterator(final K from) { public Iterator<Entry<K, V>> entryIterator(final K from, final K to) {
return new Iterator<Entry<K, V>>() { return new Iterator<Entry<K, V>>() {
private Entry<K, V> current; private Entry<K, V> current;
private K currentKey = from; private K currentKey = from;
...@@ -1507,6 +1507,9 @@ public class TransactionStore { ...@@ -1507,6 +1507,9 @@ public class TransactionStore {
} }
} }
final K key = k; final K key = k;
if (to != null && map.getKeyType().compare(k, to) > 0) {
break;
}
VersionedValue data = cursor.getValue(); VersionedValue data = cursor.getValue();
data = getValue(key, readLogId, data); data = getValue(key, readLogId, data);
if (data != null && data.value != null) { if (data != null && data.value != null) {
......
...@@ -18,6 +18,7 @@ import java.sql.ResultSet; ...@@ -18,6 +18,7 @@ import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Savepoint; import java.sql.Savepoint;
import java.sql.Statement; import java.sql.Statement;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.engine.Constants; import org.h2.engine.Constants;
...@@ -85,6 +86,7 @@ public class TestMVTableEngine extends TestBase { ...@@ -85,6 +86,7 @@ public class TestMVTableEngine extends TestBase {
testDataTypes(); testDataTypes();
testLocking(); testLocking();
testSimple(); testSimple();
testReverseDeletePerformance();
} }
private void testLobCopy() throws Exception { private void testLobCopy() throws Exception {
...@@ -1478,4 +1480,33 @@ public class TestMVTableEngine extends TestBase { ...@@ -1478,4 +1480,33 @@ public class TestMVTableEngine extends TestBase {
conn.close(); conn.close();
} }
private void testReverseDeletePerformance() throws Exception {
long direct = 0;
long reverse = 0;
for (int i = 0; i < 5; i++) {
reverse += testReverseDeletePerformance(true);
direct += testReverseDeletePerformance(false);
}
System.out.println("direct: " + direct + ", reverse: " + reverse);
assertTrue("direct: " + direct + ", reverse: " + reverse, 2 * Math.abs(reverse - direct) < reverse + direct);
}
private long testReverseDeletePerformance(boolean reverse) throws Exception {
deleteDb(getTestName());
String dbName = getTestName() + ";MV_STORE=TRUE";
try (Connection conn = getConnection(dbName)) {
Statement stat = conn.createStatement();
stat.execute("CREATE TABLE test(id INT PRIMARY KEY, name VARCHAR) AS SELECT x, x || space(1024) || x FROM system_range(1, 1000)");
conn.setAutoCommit(false);
PreparedStatement prep = conn.prepareStatement("DELETE FROM test WHERE id = ?");
long start = System.nanoTime();
for (int i = 0; i < 1000; i++) {
prep.setInt(1, reverse ? 1000 - i : i);
prep.execute();
}
long end = System.nanoTime();
conn.commit();
return TimeUnit.NANOSECONDS.toMillis(end - start);
}
}
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论