提交 038b19b6 authored 作者: Andrei Tokar's avatar Andrei Tokar

move RootReference to the top level

上级 fad4a812
......@@ -1420,111 +1420,6 @@ public class MVMap<K, V> extends AbstractMap<K, V>
return asString(null);
}
public static final class RootReference
{
/**
* The root page.
*/
public final Page root;
/**
* The version used for writing.
*/
public final long version;
/**
* Indicator that map is locked for update.
*/
final boolean lockedForUpdate;
/**
* Reference to the previous root in the chain.
*/
public volatile RootReference previous;
/**
* Counter for successful root updates.
*/
public final long updateCounter;
/**
* Counter for attempted root updates.
*/
public final long updateAttemptCounter;
/**
* Size of the occupied part of the append buffer.
*/
public final byte appendCounter;
RootReference(Page root, long version, RootReference previous, int appendCounter, long updateCounter,
long updateAttemptCounter) {
this.root = root;
this.version = version;
this.previous = previous;
this.updateCounter = updateCounter;
this.updateAttemptCounter = updateAttemptCounter;
this.lockedForUpdate = false;
this.appendCounter = (byte)appendCounter;
}
// This one is used for locking
RootReference(RootReference r, int attempt) {
this.root = r.root;
this.version = r.version;
this.previous = r.previous;
this.updateCounter = r.updateCounter + 1;
this.updateAttemptCounter = r.updateAttemptCounter + attempt;
this.lockedForUpdate = true;
this.appendCounter = r.appendCounter;
}
// This one is used for unlocking
RootReference(RootReference r, Page root, int appendCounter, boolean lockedForUpdate) {
this.root = root;
this.version = r.version;
this.previous = r.previous;
this.updateCounter = r.updateCounter;
this.updateAttemptCounter = r.updateAttemptCounter;
this.lockedForUpdate = lockedForUpdate;
this.appendCounter = (byte)appendCounter;
}
// This one is used for version change
RootReference(RootReference r, long version, int attempt) {
RootReference previous = r;
RootReference tmp;
while ((tmp = previous.previous) != null && tmp.root == r.root) {
previous = tmp;
}
this.root = r.root;
this.version = version;
this.previous = previous;
this.updateCounter = r.updateCounter + 1;
this.updateAttemptCounter = r.updateAttemptCounter + attempt;
this.lockedForUpdate = r.lockedForUpdate;
this.appendCounter = r.appendCounter;
}
// This one is used for r/o snapshots
RootReference(Page root, long version) {
this.root = root;
this.version = version;
this.previous = null;
this.updateCounter = 1;
this.updateAttemptCounter = 1;
this.lockedForUpdate = false;
this.appendCounter = 0;
}
public int getAppendCounter() {
return appendCounter & 0xff;
}
public long getTotalCount() {
return root.getTotalCount() + getAppendCounter();
}
@Override
public String toString() {
return "RootReference("+ System.identityHashCode(root)+","+version+","+ lockedForUpdate +")";
}
}
/**
* A builder for maps.
*
......
......@@ -1250,7 +1250,7 @@ public class MVStore implements AutoCloseable {
ArrayList<Page> changed = new ArrayList<>();
for (Iterator<MVMap<?, ?>> iter = maps.values().iterator(); iter.hasNext(); ) {
MVMap<?, ?> map = iter.next();
MVMap.RootReference rootReference = map.setWriteVersion(version);
RootReference rootReference = map.setWriteVersion(version);
if (rootReference == null) {
assert map.isClosed();
assert map.getVersion() < getOldestVersionToKeep();
......@@ -1289,7 +1289,7 @@ public class MVStore implements AutoCloseable {
}
}
applyFreedSpace();
MVMap.RootReference metaRootReference = meta.setWriteVersion(version);
RootReference metaRootReference = meta.setWriteVersion(version);
assert metaRootReference != null;
assert metaRootReference.version == version : metaRootReference.version + " != " + version;
metaChanged = false;
......@@ -1445,9 +1445,9 @@ public class MVStore implements AutoCloseable {
try {
ChunkIdsCollector collector = new ChunkIdsCollector(meta.getId());
long oldestVersionToKeep = getOldestVersionToKeep();
MVMap.RootReference rootReference = meta.flushAndGetRoot();
RootReference rootReference = meta.flushAndGetRoot();
if (fast) {
MVMap.RootReference previous;
RootReference previous;
while (rootReference.version >= oldestVersionToKeep && (previous = rootReference.previous) != null) {
rootReference = previous;
}
......@@ -1482,7 +1482,7 @@ public class MVStore implements AutoCloseable {
* @param inspectedRoots set of page positions for map's roots already inspected
* or null if not to be used
*/
private void inspectVersion(MVMap.RootReference rootReference, ChunkIdsCollector collector,
private void inspectVersion(RootReference rootReference, ChunkIdsCollector collector,
ThreadPoolExecutor executorService,
AtomicInteger executingThreadCounter,
Set<Long> inspectedRoots) {
......@@ -2683,7 +2683,7 @@ public class MVStore implements AutoCloseable {
DataUtils.checkArgument(map != meta,
"Removing the meta map is not allowed");
map.close();
MVMap.RootReference rootReference = map.getRoot();
RootReference rootReference = map.getRoot();
updateCounter += rootReference.updateCounter;
updateAttemptCounter += rootReference.updateAttemptCounter;
......@@ -2983,11 +2983,11 @@ public class MVStore implements AutoCloseable {
public double getUpdateFailureRatio() {
long updateCounter = this.updateCounter;
long updateAttemptCounter = this.updateAttemptCounter;
MVMap.RootReference rootReference = meta.getRoot();
RootReference rootReference = meta.getRoot();
updateCounter += rootReference.updateCounter;
updateAttemptCounter += rootReference.updateAttemptCounter;
for (MVMap<?, ?> map : maps.values()) {
MVMap.RootReference root = map.getRoot();
RootReference root = map.getRoot();
updateCounter += root.updateCounter;
updateAttemptCounter += root.updateAttemptCounter;
}
......
/*
* Copyright 2004-2019 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.mvstore;
/**
* Class RootReference.
*
* @author <a href='mailto:andrei.tokar@gmail.com'>Andrei Tokar</a>
*/
public final class RootReference {
/**
* The root page.
*/
public final Page root;
/**
* The version used for writing.
*/
public final long version;
/**
* Indicator that map is locked for update.
*/
final boolean lockedForUpdate;
/**
* Reference to the previous root in the chain.
*/
public volatile RootReference previous;
/**
* Counter for successful root updates.
*/
public final long updateCounter;
/**
* Counter for attempted root updates.
*/
public final long updateAttemptCounter;
/**
* Size of the occupied part of the append buffer.
*/
public final byte appendCounter;
RootReference(Page root, long version, RootReference previous, int appendCounter, long updateCounter,
long updateAttemptCounter) {
this.root = root;
this.version = version;
this.previous = previous;
this.updateCounter = updateCounter;
this.updateAttemptCounter = updateAttemptCounter;
this.lockedForUpdate = false;
this.appendCounter = (byte) appendCounter;
}
// This one is used for locking
RootReference(RootReference r, int attempt) {
this.root = r.root;
this.version = r.version;
this.previous = r.previous;
this.updateCounter = r.updateCounter + 1;
this.updateAttemptCounter = r.updateAttemptCounter + attempt;
this.lockedForUpdate = true;
this.appendCounter = r.appendCounter;
}
// This one is used for unlocking
RootReference(RootReference r, Page root, int appendCounter, boolean lockedForUpdate) {
this.root = root;
this.version = r.version;
this.previous = r.previous;
this.updateCounter = r.updateCounter;
this.updateAttemptCounter = r.updateAttemptCounter;
this.lockedForUpdate = lockedForUpdate;
this.appendCounter = (byte) appendCounter;
}
// This one is used for version change
RootReference(RootReference r, long version, int attempt) {
RootReference previous = r;
RootReference tmp;
while ((tmp = previous.previous) != null && tmp.root == r.root) {
previous = tmp;
}
this.root = r.root;
this.version = version;
this.previous = previous;
this.updateCounter = r.updateCounter + 1;
this.updateAttemptCounter = r.updateAttemptCounter + attempt;
this.lockedForUpdate = r.lockedForUpdate;
this.appendCounter = r.appendCounter;
}
// This one is used for r/o snapshots
RootReference(Page root, long version) {
this.root = root;
this.version = version;
this.previous = null;
this.updateCounter = 1;
this.updateAttemptCounter = 1;
this.lockedForUpdate = false;
this.appendCounter = 0;
}
public int getAppendCounter() {
return appendCounter & 0xff;
}
public long getTotalCount() {
return root.getTotalCount() + getAppendCounter();
}
@Override
public String toString() {
return "RootReference(" + System.identityHashCode(root) + "," + version + "," + lockedForUpdate + ")";
}
}
......@@ -13,6 +13,7 @@ import org.h2.mvstore.CursorPos;
import org.h2.mvstore.DataUtils;
import org.h2.mvstore.MVMap;
import org.h2.mvstore.Page;
import org.h2.mvstore.RootReference;
import org.h2.mvstore.type.DataType;
/**
......
......@@ -9,6 +9,7 @@ import org.h2.mvstore.Cursor;
import org.h2.mvstore.DataUtils;
import org.h2.mvstore.MVMap;
import org.h2.mvstore.Page;
import org.h2.mvstore.RootReference;
import org.h2.mvstore.type.DataType;
import org.h2.value.VersionedValue;
......@@ -100,19 +101,19 @@ public class TransactionMap<K, V> extends AbstractMap<K, V> {
// In order to get such a "snapshot", we wait for a moment of silence,
// when none of the variables concurrently changes it's value.
BitSet committingTransactions;
MVMap.RootReference mapRootReference;
MVMap.RootReference[] undoLogRootReferences;
RootReference mapRootReference;
RootReference[] undoLogRootReferences;
long undoLogSize;
do {
committingTransactions = store.committingTransactions.get();
mapRootReference = map.flushAndGetRoot();
BitSet opentransactions = store.openTransactions.get();
undoLogRootReferences = new MVMap.RootReference[opentransactions.length()];
undoLogRootReferences = new RootReference[opentransactions.length()];
undoLogSize = 0;
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.flushAndGetRoot();
RootReference rootReference = undoLog.flushAndGetRoot();
undoLogRootReferences[i] = rootReference;
undoLogSize += rootReference.getTotalCount();
}
......@@ -156,7 +157,7 @@ public class TransactionMap<K, V> extends AbstractMap<K, V> {
} else {
// The undo logs are much smaller than the map - scan all undo logs,
// and then lookup relevant map entry.
for (MVMap.RootReference undoLogRootReference : undoLogRootReferences) {
for (RootReference undoLogRootReference : undoLogRootReferences) {
if (undoLogRootReference != null) {
Cursor<Long, Object[]> cursor = new Cursor<>(undoLogRootReference.root, null);
while (cursor.hasNext()) {
......@@ -688,7 +689,7 @@ public class TransactionMap<K, V> extends AbstractMap<K, V> {
// In order to get such a "snapshot", we wait for a moment of silence,
// when neither of the variables concurrently changes it's value.
BitSet committingTransactions;
MVMap.RootReference mapRootReference;
RootReference mapRootReference;
do {
committingTransactions = store.committingTransactions.get();
mapRootReference = map.flushAndGetRoot();
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论