Unverified 提交 a00b17bd authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov 提交者: GitHub

Merge pull request #1318 from h2database/mode-append

Mode append fo MVPlainTempResult
......@@ -779,6 +779,12 @@ public class MVMap<K, V> extends AbstractMap<K, V>
}
public final RootReference getRoot() {
RootReference rootReference = getRootInternal();
return singleWriter && rootReference.getAppendCounter() > 0 ?
flushAppendBuffer(rootReference) : rootReference;
}
private RootReference getRootInternal() {
return root.get();
}
......@@ -1112,7 +1118,6 @@ public class MVMap<K, V> extends AbstractMap<K, V>
}
return rootReference;
}
rootReference = flushAppendBuffer(rootReference);
RootReference updatedRootReference = new RootReference(rootReference, writeVersion, ++attempt);
if(root.compareAndSet(rootReference, updatedRootReference)) {
removeUnusedOldVersions(updatedRootReference);
......@@ -1173,58 +1178,40 @@ public class MVMap<K, V> extends AbstractMap<K, V>
/**
* If map was used in append mode, this method will ensure that append buffer
* is flushed - emptied with all entries inserted into map as a new leaf.
* @param rootReference current RootReference
* @return potentially updated RootReference
*/
public RootReference flushAppendBuffer() {
return flushAppendBuffer(null);
}
private RootReference flushAppendBuffer(RootReference rootReference) {
beforeWrite();
int attempt = 0;
while(true) {
if (rootReference == null) {
rootReference = getRoot();
}
int keyCount = rootReference.getAppendCounter();
if (keyCount == 0) {
break;
}
int keyCount;
while((keyCount = rootReference.getAppendCounter()) > 0) {
Page page = Page.create(this,
Arrays.copyOf(keysBuffer, keyCount),
Arrays.copyOf(valuesBuffer, keyCount),
null, keyCount, 0);
rootReference = appendLeafPage(rootReference, page, ++attempt);
if (rootReference != null) {
break;
}
}
assert rootReference.getAppendCounter() == 0;
return rootReference;
}
private RootReference appendLeafPage(RootReference rootReference, Page split, int attempt) {
CursorPos pos = rootReference.root.getAppendCursorPos(null);
assert split.map == this;
assert page.map == this;
assert pos != null;
assert split.getKeyCount() > 0;
Object key = split.getKey(0);
assert page.getKeyCount() > 0;
Object key = page.getKey(0);
assert pos.index < 0 : pos.index;
int index = -pos.index - 1;
assert index == pos.page.getKeyCount() : index + " != " + pos.page.getKeyCount();
Page p = pos.page;
pos = pos.parent;
CursorPos tip = pos;
int unsavedMemory = 0;
int unsavedMemory = page.getMemory();
while (true) {
if (pos == null) {
if (p.getKeyCount() == 0) {
p = split;
p = page;
} else {
Object keys[] = new Object[] { key };
Page.PageReference children[] = new Page.PageReference[] {
new Page.PageReference(p),
new Page.PageReference(split)};
p = Page.create(this, keys, null, children, p.getTotalCount() + split.getTotalCount(), 0);
new Page.PageReference(page)};
p = Page.create(this, keys, null, children, p.getTotalCount() + page.getTotalCount(), 0);
}
break;
}
......@@ -1233,17 +1220,16 @@ public class MVMap<K, V> extends AbstractMap<K, V>
index = pos.index;
pos = pos.parent;
p = p.copy();
p.setChild(index, split);
p.setChild(index, page);
p.insertNode(index, key, c);
int keyCount;
if ((keyCount = p.getKeyCount()) <= store.getKeysPerPage() &&
(p.getMemory() < store.getMaxPageSize() || keyCount <= (p.isLeaf() ? 1 : 2))) {
break;
}
int at = keyCount - 2;
key = p.getKey(at);
split = p.split(at);
unsavedMemory += p.getMemory() + split.getMemory();
page = p.split(at);
unsavedMemory += p.getMemory() + page.getMemory();
}
unsavedMemory += p.getMemory();
while (pos != null) {
......@@ -1263,9 +1249,12 @@ public class MVMap<K, V> extends AbstractMap<K, V>
if (store.getFileStore() != null) {
store.registerUnsavedPage(unsavedMemory);
}
assert updatedRootReference.getAppendCounter() == 0;
return updatedRootReference;
}
return null;
rootReference = getRootInternal();
}
return rootReference;
}
/**
......@@ -1280,7 +1269,7 @@ public class MVMap<K, V> extends AbstractMap<K, V>
int attempt = 0;
boolean success = false;
while(!success) {
RootReference rootReference = getRoot();
RootReference rootReference = getRootInternal();
int appendCounter = rootReference.getAppendCounter();
if (appendCounter >= keysPerPage) {
rootReference = flushAppendBuffer(rootReference);
......
......@@ -3018,7 +3018,7 @@ public class MVStore {
// no thread is started if the write delay is 0
// (if we only had a setter in the MVStore,
// the thread would need to be started in any case)
set("autoCommitBufferSize", 0);
//set("autoCommitBufferSize", 0);
return set("autoCommitDelay", 0);
}
......
......@@ -61,14 +61,15 @@ class MVPlainTempResult extends MVTempResult {
MVPlainTempResult(Database database, Expression[] expressions, int visibleColumnCount) {
super(database, expressions.length, visibleColumnCount);
ValueDataType valueType = new ValueDataType(database.getCompareMode(), database, new int[columnCount]);
Builder<Long, ValueArray> builder = new MVMap.Builder<Long, ValueArray>().valueType(valueType);
Builder<Long, ValueArray> builder = new MVMap.Builder<Long, ValueArray>()
.valueType(valueType).singleWriter();
map = store.openMap("tmp", builder);
}
@Override
public int addRow(Value[] values) {
assert parent == null;
map.put(counter++, ValueArray.get(values));
map.append(counter++, ValueArray.get(values));
return ++rowCount;
}
......
......@@ -83,7 +83,6 @@ public final class MVSecondaryIndex extends BaseIndex implements MVIndex {
ValueArray key = convertToKey(row);
map.append(key, ValueNull.INSTANCE);
}
map.flushAppendBuffer();
}
private static final class Source {
......
......@@ -160,7 +160,7 @@ public abstract class MVTempResult implements ResultExternal {
MVTempResult(Database database, int columnCount, int visibleColumnCount) {
try {
String fileName = FileUtils.createTempFile("h2tmp", Constants.SUFFIX_TEMP_FILE, false, true);
Builder builder = new MVStore.Builder().fileName(fileName);
Builder builder = new MVStore.Builder().fileName(fileName).cacheSize(0).autoCommitDisabled();
byte[] key = database.getFileEncryptionKey();
if (key != null) {
builder.encryptionKey(MVTableEngine.decodePassword(key));
......
......@@ -88,7 +88,7 @@ public class TransactionMap<K, V> {
for (int i = opentransactions.nextSetBit(0); i >= 0; i = opentransactions.nextSetBit(i+1)) {
MVMap<Long, Object[]> undoLog = store.undoLogs[i];
if (undoLog != null) {
MVMap.RootReference rootReference = undoLog.flushAppendBuffer();
MVMap.RootReference rootReference = undoLog.getRoot();
undoLogRootReferences[i] = rootReference;
undoLogSize += rootReference.root.getTotalCount() + rootReference.getAppendCounter();
}
......
......@@ -439,9 +439,7 @@ public class TransactionStore {
store.renameMap(undoLog, getUndoLogName(true, transactionId));
}
try {
MVMap.RootReference rootReference = undoLog.flushAppendBuffer();
Page rootPage = rootReference.root;
Cursor<Long, Object[]> cursor = new Cursor<>(rootPage, null);
Cursor<Long, Object[]> cursor = undoLog.cursor(null);
while (cursor.hasNext()) {
Long undoKey = cursor.next();
Object[] op = cursor.getValue();
......@@ -592,7 +590,6 @@ public class TransactionStore {
void rollbackTo(Transaction t, long maxLogId, long toLogId) {
int transactionId = t.getId();
MVMap<Long, Object[]> undoLog = undoLogs[transactionId];
undoLog.flushAppendBuffer();
RollbackDecisionMaker decisionMaker = new RollbackDecisionMaker(this, transactionId, toLogId, t.listener);
for (long logId = maxLogId - 1; logId >= toLogId; logId--) {
Long undoKey = getOperationId(transactionId, logId);
......@@ -614,7 +611,6 @@ public class TransactionStore {
final long toLogId) {
final MVMap<Long, Object[]> undoLog = undoLogs[t.getId()];
undoLog.flushAppendBuffer();
return new Iterator<Change>() {
private long logId = maxLogId - 1;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论