提交 12afe134 authored 作者: Noel Grandin's avatar Noel Grandin

FileStore count fields need to be atomically accessed

shows up as random failures in the TestMVStore.testFastDelete test case
上级 45ff40c5
...@@ -10,7 +10,7 @@ import java.nio.ByteBuffer; ...@@ -10,7 +10,7 @@ import java.nio.ByteBuffer;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.nio.channels.FileLock; import java.nio.channels.FileLock;
import java.nio.channels.OverlappingFileLockException; import java.nio.channels.OverlappingFileLockException;
import java.util.concurrent.atomic.AtomicLong;
import org.h2.mvstore.cache.FilePathCache; import org.h2.mvstore.cache.FilePathCache;
import org.h2.store.fs.FilePath; import org.h2.store.fs.FilePath;
import org.h2.store.fs.FilePathDisk; import org.h2.store.fs.FilePathDisk;
...@@ -27,22 +27,22 @@ public class FileStore { ...@@ -27,22 +27,22 @@ public class FileStore {
/** /**
* The number of read operations. * The number of read operations.
*/ */
protected long readCount; protected final AtomicLong readCount = new AtomicLong(0);
/** /**
* The number of read bytes. * The number of read bytes.
*/ */
protected long readBytes; protected final AtomicLong readBytes = new AtomicLong(0);
/** /**
* The number of write operations. * The number of write operations.
*/ */
protected long writeCount; protected final AtomicLong writeCount = new AtomicLong(0);
/** /**
* The number of written bytes. * The number of written bytes.
*/ */
protected long writeBytes; protected final AtomicLong writeBytes = new AtomicLong(0);
/** /**
* The free spaces between the chunks. The first block to use is block 2 * The free spaces between the chunks. The first block to use is block 2
...@@ -96,8 +96,8 @@ public class FileStore { ...@@ -96,8 +96,8 @@ public class FileStore {
public ByteBuffer readFully(long pos, int len) { public ByteBuffer readFully(long pos, int len) {
ByteBuffer dst = ByteBuffer.allocate(len); ByteBuffer dst = ByteBuffer.allocate(len);
DataUtils.readFully(file, pos, dst); DataUtils.readFully(file, pos, dst);
readCount++; readCount.incrementAndGet();
readBytes += len; readBytes.addAndGet(len);
return dst; return dst;
} }
...@@ -111,8 +111,8 @@ public class FileStore { ...@@ -111,8 +111,8 @@ public class FileStore {
int len = src.remaining(); int len = src.remaining();
fileSize = Math.max(fileSize, pos + len); fileSize = Math.max(fileSize, pos + len);
DataUtils.writeFully(file, pos, src); DataUtils.writeFully(file, pos, src);
writeCount++; writeCount.incrementAndGet();
writeBytes += len; writeBytes.addAndGet(len);
} }
/** /**
...@@ -231,7 +231,7 @@ public class FileStore { ...@@ -231,7 +231,7 @@ public class FileStore {
*/ */
public void truncate(long size) { public void truncate(long size) {
try { try {
writeCount++; writeCount.incrementAndGet();
file.truncate(size); file.truncate(size);
fileSize = Math.min(fileSize, size); fileSize = Math.min(fileSize, size);
} catch (IOException e) { } catch (IOException e) {
...@@ -273,7 +273,7 @@ public class FileStore { ...@@ -273,7 +273,7 @@ public class FileStore {
* @return the number of write operations * @return the number of write operations
*/ */
public long getWriteCount() { public long getWriteCount() {
return writeCount; return writeCount.get();
} }
/** /**
...@@ -282,7 +282,7 @@ public class FileStore { ...@@ -282,7 +282,7 @@ public class FileStore {
* @return the number of write operations * @return the number of write operations
*/ */
public long getWriteBytes() { public long getWriteBytes() {
return writeBytes; return writeBytes.get();
} }
/** /**
...@@ -292,7 +292,7 @@ public class FileStore { ...@@ -292,7 +292,7 @@ public class FileStore {
* @return the number of read operations * @return the number of read operations
*/ */
public long getReadCount() { public long getReadCount() {
return readCount; return readCount.get();
} }
/** /**
...@@ -301,7 +301,7 @@ public class FileStore { ...@@ -301,7 +301,7 @@ public class FileStore {
* @return the number of write operations * @return the number of write operations
*/ */
public long getReadBytes() { public long getReadBytes() {
return readBytes; return readBytes.get();
} }
public boolean isReadOnly() { public boolean isReadOnly() {
......
...@@ -1292,7 +1292,7 @@ public final class MVStore { ...@@ -1292,7 +1292,7 @@ public final class MVStore {
private Set<Integer> collectReferencedChunks() { private Set<Integer> collectReferencedChunks() {
long testVersion = lastChunk.version; long testVersion = lastChunk.version;
DataUtils.checkArgument(testVersion > 0, "Collect references on version 0"); DataUtils.checkArgument(testVersion > 0, "Collect references on version 0");
long readCount = getFileStore().readCount; long readCount = getFileStore().readCount.get();
Set<Integer> referenced = New.hashSet(); Set<Integer> referenced = New.hashSet();
for (Cursor<String, String> c = meta.cursor("root."); c.hasNext();) { for (Cursor<String, String> c = meta.cursor("root."); c.hasNext();) {
String key = c.next(); String key = c.next();
...@@ -1308,7 +1308,7 @@ public final class MVStore { ...@@ -1308,7 +1308,7 @@ public final class MVStore {
} }
long pos = lastChunk.metaRootPos; long pos = lastChunk.metaRootPos;
collectReferencedChunks(referenced, 0, pos, 0); collectReferencedChunks(referenced, 0, pos, 0);
readCount = fileStore.readCount - readCount; readCount = fileStore.readCount.get() - readCount;
return referenced; return referenced;
} }
......
...@@ -37,8 +37,8 @@ public class OffHeapStore extends FileStore { ...@@ -37,8 +37,8 @@ public class OffHeapStore extends FileStore {
DataUtils.ERROR_READING_FAILED, DataUtils.ERROR_READING_FAILED,
"Could not read from position {0}", pos); "Could not read from position {0}", pos);
} }
readCount++; readCount.incrementAndGet();
readBytes += len; readBytes.addAndGet(len);
ByteBuffer buff = memEntry.getValue(); ByteBuffer buff = memEntry.getValue();
ByteBuffer read = buff.duplicate(); ByteBuffer read = buff.duplicate();
int offset = (int) (pos - memEntry.getKey()); int offset = (int) (pos - memEntry.getKey());
...@@ -80,8 +80,8 @@ public class OffHeapStore extends FileStore { ...@@ -80,8 +80,8 @@ public class OffHeapStore extends FileStore {
"Could not write to position {0}; " + "Could not write to position {0}; " +
"partial overwrite is not supported", pos); "partial overwrite is not supported", pos);
} }
writeCount++; writeCount.incrementAndGet();
writeBytes += length; writeBytes.addAndGet(length);
buff.rewind(); buff.rewind();
buff.put(src); buff.put(src);
return; return;
...@@ -97,8 +97,8 @@ public class OffHeapStore extends FileStore { ...@@ -97,8 +97,8 @@ public class OffHeapStore extends FileStore {
private void writeNewEntry(long pos, ByteBuffer src) { private void writeNewEntry(long pos, ByteBuffer src) {
int length = src.remaining(); int length = src.remaining();
writeCount++; writeCount.incrementAndGet();
writeBytes += length; writeBytes.addAndGet(length);
ByteBuffer buff = ByteBuffer.allocateDirect(length); ByteBuffer buff = ByteBuffer.allocateDirect(length);
buff.put(src); buff.put(src);
buff.rewind(); buff.rewind();
...@@ -107,7 +107,7 @@ public class OffHeapStore extends FileStore { ...@@ -107,7 +107,7 @@ public class OffHeapStore extends FileStore {
@Override @Override
public void truncate(long size) { public void truncate(long size) {
writeCount++; writeCount.incrementAndGet();
if (size == 0) { if (size == 0) {
fileSize = 0; fileSize = 0;
memory.clear(); memory.clear();
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论