提交 369bc80a authored 作者: Thomas Mueller's avatar Thomas Mueller

MVStore: updates that affected many rows were were slow in some cases if there…

MVStore: updates that affected many rows were were slow in some cases if there was a secondary index.
上级 999e267c
...@@ -76,7 +76,6 @@ MVStore: ...@@ -76,7 +76,6 @@ MVStore:
- temporary file storage - temporary file storage
- simple rollback method (rollback to last committed version) - simple rollback method (rollback to last committed version)
- MVMap to implement SortedMap, then NavigableMap - MVMap to implement SortedMap, then NavigableMap
- Test with OSGi
- storage that splits database into multiple files, - storage that splits database into multiple files,
to speed up compact and allow using trim to speed up compact and allow using trim
(by truncating / deleting empty files) (by truncating / deleting empty files)
......
...@@ -127,16 +127,8 @@ public class MVSecondaryIndex extends BaseIndex implements MVIndex { ...@@ -127,16 +127,8 @@ public class MVSecondaryIndex extends BaseIndex implements MVIndex {
array = Arrays.copyOf(array, array.length); array = Arrays.copyOf(array, array.length);
array[keyColumns - 1] = ValueLong.get(Long.MIN_VALUE); array[keyColumns - 1] = ValueLong.get(Long.MIN_VALUE);
ValueArray unique = ValueArray.get(array); ValueArray unique = ValueArray.get(array);
ValueArray key = (ValueArray) dataMap.getLatestCeilingKey(unique); SearchRow row = convertToSearchRow((ValueArray) v);
if (key != null) { checkUnique(row, dataMap, unique);
SearchRow r2 = convertToSearchRow(key);
SearchRow row = convertToSearchRow((ValueArray) v);
if (compareRows(row, r2) == 0) {
if (!containsNullAndAllowMultipleNull(r2)) {
throw getDuplicateKeyException(key.toString());
}
}
}
} }
dataMap.putCommitted(v, ValueNull.INSTANCE); dataMap.putCommitted(v, ValueNull.INSTANCE);
...@@ -195,15 +187,7 @@ public class MVSecondaryIndex extends BaseIndex implements MVIndex { ...@@ -195,15 +187,7 @@ public class MVSecondaryIndex extends BaseIndex implements MVIndex {
// this will detect committed entries only // this will detect committed entries only
unique = convertToKey(row); unique = convertToKey(row);
unique.getList()[keyColumns - 1] = ValueLong.get(Long.MIN_VALUE); unique.getList()[keyColumns - 1] = ValueLong.get(Long.MIN_VALUE);
ValueArray key = (ValueArray) map.getLatestCeilingKey(unique); checkUnique(row, map, unique);
if (key != null) {
SearchRow r2 = convertToSearchRow(key);
if (compareRows(row, r2) == 0) {
if (!containsNullAndAllowMultipleNull(r2)) {
throw getDuplicateKeyException(key.toString());
}
}
}
} }
try { try {
map.put(array, ValueNull.INSTANCE); map.put(array, ValueNull.INSTANCE);
...@@ -234,6 +218,23 @@ public class MVSecondaryIndex extends BaseIndex implements MVIndex { ...@@ -234,6 +218,23 @@ public class MVSecondaryIndex extends BaseIndex implements MVIndex {
} }
} }
} }
private void checkUnique(SearchRow row, TransactionMap<Value, Value> map, ValueArray unique) {
Iterator<Value> it = map.keyIterator(unique, true);
while (it.hasNext()) {
ValueArray k = (ValueArray) it.next();
SearchRow r2 = convertToSearchRow(k);
if (compareRows(row, r2) != 0) {
break;
}
if (map.get(k) != null) {
if (!containsNullAndAllowMultipleNull(r2)) {
throw getDuplicateKeyException(k.toString());
}
}
}
}
@Override @Override
public void remove(Session session, Row row) { public void remove(Session session, Row row) {
......
...@@ -414,8 +414,6 @@ public class MVTable extends TableBase { ...@@ -414,8 +414,6 @@ public class MVTable extends TableBase {
database.lockMeta(session); database.lockMeta(session);
} }
MVIndex index; MVIndex index;
// TODO support in-memory indexes
// if (isPersistIndexes() && indexType.isPersistent()) {
int mainIndexColumn; int mainIndexColumn;
mainIndexColumn = getMainIndexColumn(indexType, cols); mainIndexColumn = getMainIndexColumn(indexType, cols);
if (database.isStarting()) { if (database.isStarting()) {
......
...@@ -1308,23 +1308,6 @@ public class TransactionStore { ...@@ -1308,23 +1308,6 @@ public class TransactionStore {
} }
} }
/**
* Get the most recent smallest key that is larger or equal to this key.
*
* @param key the key (may not be null)
* @return the result
*/
public K getLatestCeilingKey(K key) {
Iterator<K> cursor = map.keyIterator(key);
while (cursor.hasNext()) {
key = cursor.next();
if (get(key, Long.MAX_VALUE) != null) {
return key;
}
}
return null;
}
/** /**
* Get the smallest key that is larger than the given key, or null if no * Get the smallest key that is larger than the given key, or null if no
* such key exists. * such key exists.
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论