提交 9e6867b0 authored 作者: Thomas Mueller's avatar Thomas Mueller

The spatial index now works in MVCC mode when using the MVStore storage.

上级 b5ede1e6
......@@ -21,6 +21,7 @@ Change Log
<ul><li>Subqueries or views with "order by" an alias expression could not be executed
due to a regression introduced in version 1.3.174.
</li><li>Issue 73: MySQL compatibility: support REPLACE, patch by Cemo Koc.
</li><li>The spatial index now works in MVCC mode when using the MVStore storage.
</li><li>MVStore: concurrency problems have been fixed.
</li><li>Improve error message when dropping an index that belongs to a constraint,
specify constraint in error message.
......
......@@ -194,7 +194,6 @@ public class SpatialTreeIndex extends BaseIndex implements SpatialIndex {
@Override
public void remove(Session session) {
if (!treeMap.isClosed()) {
MVStore store = session.getDatabase().getMvStore().getStore();
store.removeMap(treeMap);
}
}
......
......@@ -379,8 +379,7 @@ public class MVPrimaryIndex extends BaseIndex {
@Override
public boolean previous() {
// TODO previous
return false;
throw DbException.getUnsupportedException("previous");
}
}
......
......@@ -342,8 +342,7 @@ public class MVSecondaryIndex extends BaseIndex {
@Override
public boolean previous() {
// TODO previous
return false;
throw DbException.getUnsupportedException("previous");
}
}
......
......@@ -26,7 +26,6 @@ import org.h2.index.Cursor;
import org.h2.index.Index;
import org.h2.index.IndexType;
import org.h2.index.MultiVersionIndex;
import org.h2.index.SpatialTreeIndex;
import org.h2.message.DbException;
import org.h2.message.Trace;
import org.h2.mvstore.db.TransactionStore.Transaction;
......@@ -399,9 +398,9 @@ public class MVTable extends TableBase {
index = new MVDelegateIndex(this, indexId,
indexName, primaryIndex, indexType);
} else if (indexType.isSpatial()) {
int todo;
index = new SpatialTreeIndex(this, indexId, indexName, cols,
indexType, true, create, session);
index = new MVSpatialIndex(session.getDatabase(),
this, indexId,
indexName, cols, indexType);
} else {
index = new MVSecondaryIndex(session.getDatabase(),
this, indexId,
......
......@@ -173,9 +173,9 @@ public class MVTableEngine implements TableEngine {
if (s == null || s.isReadOnly()) {
return;
}
store.commit();
store.compact(50);
store.store();
if (!store.compact(50)) {
store.store();
}
}
/**
......
......@@ -170,7 +170,7 @@ public class TransactionStore {
public synchronized void close() {
// to avoid losing transaction ids
settings.put(LAST_TRANSACTION_ID, "" + lastTransactionId);
store.commit();
store.store();
}
/**
......@@ -658,9 +658,8 @@ public class TransactionStore {
return new TransactionMap<K, V>(this, map, mapId);
}
public <K, V> TransactionMap<K, V> openMap(String name, MVMap.Builder<K, VersionedValue> builder) {
public <K, V> TransactionMap<K, V> openMap(MVMap<K, VersionedValue> map) {
checkNotClosed();
MVMap<K, VersionedValue> map = store.store.openMap(name, builder);
int mapId = map.getId();
return new TransactionMap<K, V>(this, map, mapId);
}
......@@ -1214,11 +1213,11 @@ public class TransactionStore {
/**
* Iterate over keys.
*
* @param cursor the wrapped cursor
* @param iterator the iterator to wrap
* @param includeUncommitted whether uncommitted entries should be included
* @return the iterator
*/
private Iterator<K> wrapIterator(final Cursor<K> cursor, final boolean includeUncommitted) {
public Iterator<K> wrapIterator(final Iterator<K> iterator, final boolean includeUncommitted) {
return new Iterator<K>() {
private K current;
......@@ -1227,8 +1226,8 @@ public class TransactionStore {
}
private void fetchNext() {
while (cursor.hasNext()) {
current = cursor.next();
while (iterator.hasNext()) {
current = iterator.next();
if (includeUncommitted) {
return;
}
......
......@@ -17,6 +17,8 @@ import org.h2.constant.ErrorCode;
import org.h2.message.DbException;
import org.h2.mvstore.DataUtils;
import org.h2.mvstore.WriteBuffer;
import org.h2.mvstore.rtree.SpatialDataType;
import org.h2.mvstore.rtree.SpatialKey;
import org.h2.mvstore.type.DataType;
import org.h2.result.SortOrder;
import org.h2.store.DataHandler;
......@@ -68,10 +70,12 @@ public class ValueDataType implements DataType {
private static final int LONG_NEG = 67;
private static final int STRING_0_31 = 68;
private static final int BYTES_0_31 = 100;
private static final int SPATIAL_KEY_2D = 132;
final DataHandler handler;
final CompareMode compareMode;
final int[] sortTypes;
final SpatialDataType spatialType = new SpatialDataType(2);
public ValueDataType(CompareMode compareMode, DataHandler handler, int[] sortTypes) {
this.compareMode = compareMode;
......@@ -134,6 +138,9 @@ public class ValueDataType implements DataType {
@Override
public int getMemory(Object obj) {
if (obj instanceof SpatialKey) {
return spatialType.getMemory(obj);
}
return getMemory((Value) obj);
}
......@@ -142,12 +149,17 @@ public class ValueDataType implements DataType {
}
@Override
public Value read(ByteBuffer buff) {
public Object read(ByteBuffer buff) {
return readValue(buff);
}
@Override
public void write(WriteBuffer buff, Object obj) {
if (obj instanceof SpatialKey) {
buff.put((byte) SPATIAL_KEY_2D);
spatialType.write(buff, obj);
return;
}
Value x = (Value) obj;
writeValue(buff, x);
}
......@@ -418,7 +430,7 @@ public class ValueDataType implements DataType {
*
* @return the value
*/
private Value readValue(ByteBuffer buff) {
private Object readValue(ByteBuffer buff) {
int type = buff.get() & 255;
switch (type) {
case Value.NULL:
......@@ -440,9 +452,9 @@ public class ValueDataType implements DataType {
case Value.SHORT:
return ValueShort.get(buff.getShort());
case DECIMAL_0_1:
return (ValueDecimal) ValueDecimal.ZERO;
return ValueDecimal.ZERO;
case DECIMAL_0_1 + 1:
return (ValueDecimal) ValueDecimal.ONE;
return ValueDecimal.ONE;
case DECIMAL_SMALL_0:
return ValueDecimal.get(BigDecimal.valueOf(readVarLong(buff)));
case DECIMAL_SMALL: {
......@@ -537,7 +549,7 @@ public class ValueDataType implements DataType {
int len = readVarInt(buff);
Value[] list = new Value[len];
for (int i = 0; i < len; i++) {
list[i] = readValue(buff);
list[i] = (Value) readValue(buff);
}
return ValueArray.get(list);
}
......@@ -553,7 +565,7 @@ public class ValueDataType implements DataType {
}
Object[] o = new Object[columns];
for (int i = 0; i < columns; i++) {
o[i] = readValue(buff).getObject();
o[i] = ((Value) readValue(buff)).getObject();
}
rs.addRow(o);
}
......@@ -565,6 +577,8 @@ public class ValueDataType implements DataType {
buff.get(b, 0, len);
return ValueGeometry.get(b);
}
case SPATIAL_KEY_2D:
return spatialType.read(buff);
default:
if (type >= INT_0_15 && type < INT_0_15 + 16) {
return ValueInt.get(type - INT_0_15);
......
......@@ -478,7 +478,7 @@ public class MVRTreeMap<V> extends MVMap<SpatialKey, V> {
/**
* A cursor to iterate over a subset of the keys.
*/
static class RTreeCursor implements Iterator<SpatialKey> {
public static class RTreeCursor implements Iterator<SpatialKey> {
private final SpatialKey filter;
private CursorPos pos;
......
......@@ -91,10 +91,25 @@ public class SpatialKey {
@Override
public boolean equals(Object other) {
if (!(other instanceof SpatialKey)) {
if (other == this) {
return true;
} else if (!(other instanceof SpatialKey)) {
return false;
}
SpatialKey o = (SpatialKey) other;
if (id != o.id) {
return false;
}
return equalsIgnoringId(o);
}
/**
* Check whether two objects are equals, but do not compare the id fields.
*
* @param o the other key
* @return true if the contents are the same
*/
public boolean equalsIgnoringId(SpatialKey o) {
return Arrays.equals(minMax, o.minMax);
}
......
......@@ -45,7 +45,7 @@ public class TestSpatial extends TestBase {
@Override
public void test() throws SQLException {
if (config.mvcc) {
if (!config.mvStore && config.mvcc) {
return;
}
if (DataType.GEOMETRY_CLASS != null) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论