mirror of
https://github.com/apache/activemq.git
synced 2025-02-20 17:05:07 +00:00
adding options for https://issues.apache.org/jira/browse/AMQ-5578 to
allow configuring the allocation strategy at finer grained controls including zeroing out, OS copying, or sparse file
This commit is contained in:
parent
8858dc294c
commit
45e59e6e83
@ -511,6 +511,22 @@ public class KahaDBPersistenceAdapter extends LockableServiceSupport implements
|
|||||||
letter.setBrokerService(brokerService);
|
letter.setBrokerService(brokerService);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getPreallocationScope() {
|
||||||
|
return letter.getPreallocationScope();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPreallocationScope(String preallocationScope) {
|
||||||
|
this.letter.setPreallocationScope(preallocationScope);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPreallocationStrategy() {
|
||||||
|
return letter.getPreallocationStrategy();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPreallocationStrategy(String preallocationStrategy) {
|
||||||
|
this.letter.setPreallocationStrategy(preallocationStrategy);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isArchiveDataLogs() {
|
public boolean isArchiveDataLogs() {
|
||||||
return letter.isArchiveDataLogs();
|
return letter.isArchiveDataLogs();
|
||||||
}
|
}
|
||||||
|
@ -237,8 +237,11 @@ public abstract class MessageDatabase extends ServiceSupport implements BrokerSe
|
|||||||
long cleanupInterval = 30*1000;
|
long cleanupInterval = 30*1000;
|
||||||
int journalMaxFileLength = Journal.DEFAULT_MAX_FILE_LENGTH;
|
int journalMaxFileLength = Journal.DEFAULT_MAX_FILE_LENGTH;
|
||||||
int journalMaxWriteBatchSize = Journal.DEFAULT_MAX_WRITE_BATCH_SIZE;
|
int journalMaxWriteBatchSize = Journal.DEFAULT_MAX_WRITE_BATCH_SIZE;
|
||||||
|
int preallocationBatchSize = Journal.DEFAULT_PREALLOCATION_BATCH_SIZE;
|
||||||
boolean enableIndexWriteAsync = false;
|
boolean enableIndexWriteAsync = false;
|
||||||
int setIndexWriteBatchSize = PageFile.DEFAULT_WRITE_BATCH_SIZE;
|
int setIndexWriteBatchSize = PageFile.DEFAULT_WRITE_BATCH_SIZE;
|
||||||
|
private String preallocationScope = Journal.PreallocationScope.ENTIRE_JOURNAL.name();
|
||||||
|
private String preallocationStrategy = Journal.PreallocationStrategy.SPARSE_FILE.name();
|
||||||
|
|
||||||
protected AtomicBoolean opened = new AtomicBoolean();
|
protected AtomicBoolean opened = new AtomicBoolean();
|
||||||
private boolean ignoreMissingJournalfiles = false;
|
private boolean ignoreMissingJournalfiles = false;
|
||||||
@ -2487,6 +2490,10 @@ public abstract class MessageDatabase extends ServiceSupport implements BrokerSe
|
|||||||
manager.setArchiveDataLogs(isArchiveDataLogs());
|
manager.setArchiveDataLogs(isArchiveDataLogs());
|
||||||
manager.setSizeAccumulator(journalSize);
|
manager.setSizeAccumulator(journalSize);
|
||||||
manager.setEnableAsyncDiskSync(isEnableJournalDiskSyncs());
|
manager.setEnableAsyncDiskSync(isEnableJournalDiskSyncs());
|
||||||
|
manager.setPreallocationScope(Journal.PreallocationScope.valueOf(preallocationScope.trim().toUpperCase()));
|
||||||
|
manager.setPreallocationStrategy(
|
||||||
|
Journal.PreallocationStrategy.valueOf(preallocationStrategy.trim().toUpperCase()));
|
||||||
|
manager.setPreallocationBatchSize(preallocationBatchSize);
|
||||||
if (getDirectoryArchive() != null) {
|
if (getDirectoryArchive() != null) {
|
||||||
IOHelper.mkdirs(getDirectoryArchive());
|
IOHelper.mkdirs(getDirectoryArchive());
|
||||||
manager.setDirectoryArchive(getDirectoryArchive());
|
manager.setDirectoryArchive(getDirectoryArchive());
|
||||||
@ -3175,4 +3182,28 @@ public abstract class MessageDatabase extends ServiceSupport implements BrokerSe
|
|||||||
interface IndexAware {
|
interface IndexAware {
|
||||||
public void sequenceAssignedWithIndexLocked(long index);
|
public void sequenceAssignedWithIndexLocked(long index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getPreallocationScope() {
|
||||||
|
return preallocationScope;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPreallocationScope(String preallocationScope) {
|
||||||
|
this.preallocationScope = preallocationScope;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPreallocationStrategy() {
|
||||||
|
return preallocationStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPreallocationStrategy(String preallocationStrategy) {
|
||||||
|
this.preallocationStrategy = preallocationStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPreallocationBatchSize() {
|
||||||
|
return preallocationBatchSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPreallocationBatchSize(int preallocationBatchSize) {
|
||||||
|
this.preallocationBatchSize = preallocationBatchSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,11 +18,16 @@ package org.apache.activemq.store.kahadb.disk.journal;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.RandomAccessFile;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.FileChannel;
|
||||||
|
|
||||||
import org.apache.activemq.store.kahadb.disk.util.LinkedNode;
|
import org.apache.activemq.store.kahadb.disk.util.LinkedNode;
|
||||||
import org.apache.activemq.store.kahadb.disk.util.SequenceSet;
|
import org.apache.activemq.store.kahadb.disk.util.SequenceSet;
|
||||||
import org.apache.activemq.util.IOHelper;
|
import org.apache.activemq.util.IOHelper;
|
||||||
import org.apache.activemq.util.RecoverableRandomAccessFile;
|
import org.apache.activemq.util.RecoverableRandomAccessFile;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DataFile
|
* DataFile
|
||||||
@ -31,10 +36,13 @@ import org.apache.activemq.util.RecoverableRandomAccessFile;
|
|||||||
*/
|
*/
|
||||||
public class DataFile extends LinkedNode<DataFile> implements Comparable<DataFile> {
|
public class DataFile extends LinkedNode<DataFile> implements Comparable<DataFile> {
|
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(DataFile.class);
|
||||||
|
|
||||||
protected final File file;
|
protected final File file;
|
||||||
protected final Integer dataFileId;
|
protected final Integer dataFileId;
|
||||||
protected volatile int length;
|
protected volatile int length;
|
||||||
protected final SequenceSet corruptedBlocks = new SequenceSet();
|
protected final SequenceSet corruptedBlocks = new SequenceSet();
|
||||||
|
protected long preallocationBatchWindow = 0L;
|
||||||
|
|
||||||
DataFile(File file, int number) {
|
DataFile(File file, int number) {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
@ -60,6 +68,7 @@ public class DataFile extends LinkedNode<DataFile> implements Comparable<DataFil
|
|||||||
|
|
||||||
public synchronized void incrementLength(int size) {
|
public synchronized void incrementLength(int size) {
|
||||||
length += size;
|
length += size;
|
||||||
|
preallocationBatchWindow -= size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -105,4 +114,39 @@ public class DataFile extends LinkedNode<DataFile> implements Comparable<DataFil
|
|||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return dataFileId;
|
return dataFileId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void preallocateJournalBatch(Journal journal, long newMessageSize) {
|
||||||
|
|
||||||
|
if (preallocationBatchWindow - newMessageSize <= 0) {
|
||||||
|
int preallocationBatchSize = Math.min(journal.getPreallocationBatchSize(),
|
||||||
|
journal.maxFileLength - length);
|
||||||
|
doPreallocation(preallocationBatchSize);
|
||||||
|
preallocationBatchWindow = preallocationBatchSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doPreallocation(int size) {
|
||||||
|
try {
|
||||||
|
RecoverableRandomAccessFile file = openRandomAccessFile();
|
||||||
|
FileChannel channel = file.getChannel();
|
||||||
|
|
||||||
|
channel.position(length+1);
|
||||||
|
ByteBuffer buffer = generateAllocation(size);
|
||||||
|
channel.write(buffer);
|
||||||
|
channel.force(false);
|
||||||
|
file.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.debug("Cannot allocate batch for journal, continue without preallocation of batch...");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private ByteBuffer generateAllocation(int size) {
|
||||||
|
ByteBuffer rc = ByteBuffer.allocate(size);
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
rc.put((byte) 0x00);
|
||||||
|
}
|
||||||
|
rc.flip();
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,6 +211,11 @@ class DataFileAppender implements FileAppender {
|
|||||||
file = journal.rotateWriteFile();
|
file = journal.rotateWriteFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// will do batch preallocation on the journal if configured
|
||||||
|
if (journal.preallocationScope == Journal.PreallocationScope.BATCH) {
|
||||||
|
file.preallocateJournalBatch(journal, write.location.getSize());
|
||||||
|
}
|
||||||
|
|
||||||
nextWriteBatch = newWriteBatch(write, file);
|
nextWriteBatch = newWriteBatch(write, file);
|
||||||
enqueueMutex.notifyAll();
|
enqueueMutex.notifyAll();
|
||||||
break;
|
break;
|
||||||
@ -314,8 +319,7 @@ class DataFileAppender implements FileAppender {
|
|||||||
dataFile = wb.dataFile;
|
dataFile = wb.dataFile;
|
||||||
file = dataFile.openRandomAccessFile();
|
file = dataFile.openRandomAccessFile();
|
||||||
// pre allocate on first open
|
// pre allocate on first open
|
||||||
file.seek(journal.maxFileLength-1);
|
journal.preallocateEntireJournalDataFile(file);
|
||||||
file.write(end);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Journal.WriteCommand write = wb.writes.getHead();
|
Journal.WriteCommand write = wb.writes.getHead();
|
||||||
|
@ -16,10 +16,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.activemq.store.kahadb.disk.journal;
|
package org.apache.activemq.store.kahadb.disk.journal;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.*;
|
||||||
import java.io.FilenameFilter;
|
import java.nio.ByteBuffer;
|
||||||
import java.io.IOException;
|
import java.nio.channels.FileChannel;
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
@ -27,12 +26,9 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||||||
import java.util.zip.Adler32;
|
import java.util.zip.Adler32;
|
||||||
import java.util.zip.Checksum;
|
import java.util.zip.Checksum;
|
||||||
import org.apache.activemq.store.kahadb.disk.util.LinkedNode;
|
import org.apache.activemq.store.kahadb.disk.util.LinkedNode;
|
||||||
import org.apache.activemq.util.IOHelper;
|
import org.apache.activemq.util.*;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.apache.activemq.util.ByteSequence;
|
|
||||||
import org.apache.activemq.util.DataByteArrayInputStream;
|
|
||||||
import org.apache.activemq.util.DataByteArrayOutputStream;
|
|
||||||
import org.apache.activemq.store.kahadb.disk.util.LinkedNodeList;
|
import org.apache.activemq.store.kahadb.disk.util.LinkedNodeList;
|
||||||
import org.apache.activemq.store.kahadb.disk.util.SchedulerTimerTask;
|
import org.apache.activemq.store.kahadb.disk.util.SchedulerTimerTask;
|
||||||
import org.apache.activemq.store.kahadb.disk.util.Sequence;
|
import org.apache.activemq.store.kahadb.disk.util.Sequence;
|
||||||
@ -58,6 +54,17 @@ public class Journal {
|
|||||||
public static final int BATCH_CONTROL_RECORD_SIZE = RECORD_HEAD_SPACE+BATCH_CONTROL_RECORD_MAGIC.length+4+8;
|
public static final int BATCH_CONTROL_RECORD_SIZE = RECORD_HEAD_SPACE+BATCH_CONTROL_RECORD_MAGIC.length+4+8;
|
||||||
public static final byte[] BATCH_CONTROL_RECORD_HEADER = createBatchControlRecordHeader();
|
public static final byte[] BATCH_CONTROL_RECORD_HEADER = createBatchControlRecordHeader();
|
||||||
|
|
||||||
|
public enum PreallocationStrategy {
|
||||||
|
SPARSE_FILE,
|
||||||
|
OS_KERNEL_COPY,
|
||||||
|
ZEROS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum PreallocationScope {
|
||||||
|
BATCH,
|
||||||
|
ENTIRE_JOURNAL;
|
||||||
|
}
|
||||||
|
|
||||||
private static byte[] createBatchControlRecordHeader() {
|
private static byte[] createBatchControlRecordHeader() {
|
||||||
try {
|
try {
|
||||||
DataByteArrayOutputStream os = new DataByteArrayOutputStream();
|
DataByteArrayOutputStream os = new DataByteArrayOutputStream();
|
||||||
@ -80,6 +87,7 @@ public class Journal {
|
|||||||
public static final int DEFAULT_CLEANUP_INTERVAL = 1000 * 30;
|
public static final int DEFAULT_CLEANUP_INTERVAL = 1000 * 30;
|
||||||
public static final int PREFERED_DIFF = 1024 * 512;
|
public static final int PREFERED_DIFF = 1024 * 512;
|
||||||
public static final int DEFAULT_MAX_WRITE_BATCH_SIZE = 1024 * 1024 * 4;
|
public static final int DEFAULT_MAX_WRITE_BATCH_SIZE = 1024 * 1024 * 4;
|
||||||
|
public static final int DEFAULT_PREALLOCATION_BATCH_SIZE = 1024 * 1024 * 1;
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(Journal.class);
|
private static final Logger LOG = LoggerFactory.getLogger(Journal.class);
|
||||||
|
|
||||||
@ -113,6 +121,10 @@ public class Journal {
|
|||||||
protected boolean enableAsyncDiskSync = true;
|
protected boolean enableAsyncDiskSync = true;
|
||||||
private Timer timer;
|
private Timer timer;
|
||||||
|
|
||||||
|
protected PreallocationScope preallocationScope = PreallocationScope.ENTIRE_JOURNAL;
|
||||||
|
protected PreallocationStrategy preallocationStrategy = PreallocationStrategy.SPARSE_FILE;
|
||||||
|
protected int preallocationBatchSize = DEFAULT_PREALLOCATION_BATCH_SIZE;
|
||||||
|
|
||||||
public interface DataFileRemovedListener {
|
public interface DataFileRemovedListener {
|
||||||
void fileRemoved(DataFile datafile);
|
void fileRemoved(DataFile datafile);
|
||||||
}
|
}
|
||||||
@ -181,6 +193,7 @@ public class Journal {
|
|||||||
totalLength.addAndGet(lastAppendLocation.get().getOffset() - maxFileLength);
|
totalLength.addAndGet(lastAppendLocation.get().getOffset() - maxFileLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
cleanupTask = new Runnable() {
|
cleanupTask = new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
cleanup();
|
cleanup();
|
||||||
@ -193,6 +206,85 @@ public class Journal {
|
|||||||
LOG.trace("Startup took: "+(end-start)+" ms");
|
LOG.trace("Startup took: "+(end-start)+" ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void preallocateEntireJournalDataFile(RecoverableRandomAccessFile file) {
|
||||||
|
|
||||||
|
if (PreallocationScope.ENTIRE_JOURNAL == preallocationScope) {
|
||||||
|
|
||||||
|
if (PreallocationStrategy.OS_KERNEL_COPY == preallocationStrategy) {
|
||||||
|
doPreallocationKernelCopy(file);
|
||||||
|
|
||||||
|
}else if (PreallocationStrategy.ZEROS == preallocationStrategy) {
|
||||||
|
doPreallocationZeros(file);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
doPreallocationSparseFile(file);
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
LOG.info("Using journal preallocation scope of batch allocation");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doPreallocationSparseFile(RecoverableRandomAccessFile file) {
|
||||||
|
LOG.info("Preallocate journal file with sparse file");
|
||||||
|
try {
|
||||||
|
file.seek(maxFileLength - 1);
|
||||||
|
file.write((byte)0x00);
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.error("Could not preallocate journal file with sparse file! Will continue without preallocation", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doPreallocationZeros(RecoverableRandomAccessFile file) {
|
||||||
|
LOG.info("Preallocate journal file with zeros");
|
||||||
|
ByteBuffer buffer = ByteBuffer.allocate(maxFileLength);
|
||||||
|
for (int i = 0; i < maxFileLength; i++) {
|
||||||
|
buffer.put((byte) 0x00);
|
||||||
|
}
|
||||||
|
buffer.flip();
|
||||||
|
|
||||||
|
try {
|
||||||
|
FileChannel channel = file.getChannel();
|
||||||
|
channel.write(buffer);
|
||||||
|
channel.force(false);
|
||||||
|
channel.position(0);
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.error("Could not preallocate journal file with zeros! Will continue without preallocation", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doPreallocationKernelCopy(RecoverableRandomAccessFile file) {
|
||||||
|
LOG.info("Preallocate journal file with kernel file copying");
|
||||||
|
|
||||||
|
// create a template file that will be used to pre-allocate the journal files
|
||||||
|
File templateFile = createJournalTemplateFile();
|
||||||
|
|
||||||
|
RandomAccessFile templateRaf = null;
|
||||||
|
try {
|
||||||
|
templateRaf = new RandomAccessFile(templateFile, "rw");
|
||||||
|
templateRaf.setLength(maxFileLength);
|
||||||
|
templateRaf.getChannel().force(true);
|
||||||
|
templateRaf.getChannel().transferTo(0, getMaxFileLength(), file.getChannel());
|
||||||
|
templateRaf.close();
|
||||||
|
templateFile.delete();
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
LOG.error("Could not find the template file on disk at " + templateFile.getAbsolutePath(), e);
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.error("Could not transfer the template file to journal, transferFile=" + templateFile.getAbsolutePath(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private File createJournalTemplateFile() {
|
||||||
|
String fileName = "db-log.template";
|
||||||
|
File rc = new File(directory, fileName);
|
||||||
|
if (rc.exists()) {
|
||||||
|
System.out.println("deleting file because it already exists...");
|
||||||
|
rc.delete();
|
||||||
|
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
private static byte[] bytes(String string) {
|
private static byte[] bytes(String string) {
|
||||||
try {
|
try {
|
||||||
return string.getBytes("UTF-8");
|
return string.getBytes("UTF-8");
|
||||||
@ -570,6 +662,30 @@ public class Journal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PreallocationStrategy getPreallocationStrategy() {
|
||||||
|
return preallocationStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPreallocationStrategy(PreallocationStrategy preallocationStrategy) {
|
||||||
|
this.preallocationStrategy = preallocationStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PreallocationScope getPreallocationScope() {
|
||||||
|
return preallocationScope;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPreallocationScope(PreallocationScope preallocationScope) {
|
||||||
|
this.preallocationScope = preallocationScope;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPreallocationBatchSize() {
|
||||||
|
return preallocationBatchSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPreallocationBatchSize(int preallocationBatchSize) {
|
||||||
|
this.preallocationBatchSize = preallocationBatchSize;
|
||||||
|
}
|
||||||
|
|
||||||
public File getDirectory() {
|
public File getDirectory() {
|
||||||
return directory;
|
return directory;
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.activemq.store.kahadb.disk.util;
|
package org.apache.activemq.store.kahadb.disk.util;
|
||||||
|
|
||||||
|
import org.apache.activemq.util.RecoverableRandomAccessFile;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.RandomAccessFile;
|
import java.io.RandomAccessFile;
|
||||||
@ -193,7 +195,7 @@ public class DiskBenchmark {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Report benchmark(File file) throws IOException {
|
public Report benchmark(File file) throws Exception {
|
||||||
Report rc = new Report();
|
Report rc = new Report();
|
||||||
|
|
||||||
// Initialize the block we will be writing to disk.
|
// Initialize the block we will be writing to disk.
|
||||||
@ -203,8 +205,9 @@ public class DiskBenchmark {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rc.size = data.length;
|
rc.size = data.length;
|
||||||
RandomAccessFile raf = new RandomAccessFile(file, "rw");
|
RecoverableRandomAccessFile raf = new RecoverableRandomAccessFile(file, "rw");
|
||||||
raf.setLength(size);
|
// RandomAccessFile raf = new RandomAccessFile(file, "rw");
|
||||||
|
preallocateDataFile(raf, file.getParentFile());
|
||||||
|
|
||||||
// Figure out how many writes we can do in the sample interval.
|
// Figure out how many writes we can do in the sample interval.
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
@ -235,7 +238,7 @@ public class DiskBenchmark {
|
|||||||
rc.writes = ioCount;
|
rc.writes = ioCount;
|
||||||
rc.writeDuration = (now - start);
|
rc.writeDuration = (now - start);
|
||||||
|
|
||||||
raf = new RandomAccessFile(file, "rw");
|
raf = new RecoverableRandomAccessFile(file, "rw");
|
||||||
start = System.currentTimeMillis();
|
start = System.currentTimeMillis();
|
||||||
now = System.currentTimeMillis();
|
now = System.currentTimeMillis();
|
||||||
ioCount = 0;
|
ioCount = 0;
|
||||||
@ -259,7 +262,7 @@ public class DiskBenchmark {
|
|||||||
rc.syncWrites = ioCount;
|
rc.syncWrites = ioCount;
|
||||||
rc.syncWriteDuration = (now - start);
|
rc.syncWriteDuration = (now - start);
|
||||||
|
|
||||||
raf = new RandomAccessFile(file, "rw");
|
raf = new RecoverableRandomAccessFile(file, "rw");
|
||||||
start = System.currentTimeMillis();
|
start = System.currentTimeMillis();
|
||||||
now = System.currentTimeMillis();
|
now = System.currentTimeMillis();
|
||||||
ioCount = 0;
|
ioCount = 0;
|
||||||
@ -285,6 +288,25 @@ public class DiskBenchmark {
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void preallocateDataFile(RecoverableRandomAccessFile raf, File location) throws Exception {
|
||||||
|
File tmpFile;
|
||||||
|
if (location != null && location.isDirectory()) {
|
||||||
|
tmpFile = new File(location, "template.dat");
|
||||||
|
}else {
|
||||||
|
tmpFile = new File("template.dat");
|
||||||
|
}
|
||||||
|
if (tmpFile.exists()) {
|
||||||
|
tmpFile.delete();
|
||||||
|
}
|
||||||
|
System.out.println("Using a template file: " + tmpFile.getAbsolutePath());
|
||||||
|
RandomAccessFile templateFile = new RandomAccessFile(tmpFile, "rw");
|
||||||
|
templateFile.setLength(size);
|
||||||
|
templateFile.getChannel().force(true);
|
||||||
|
templateFile.getChannel().transferTo(0, size, raf.getChannel());
|
||||||
|
templateFile.close();
|
||||||
|
tmpFile.delete();
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isVerbose() {
|
public boolean isVerbose() {
|
||||||
return verbose;
|
return verbose;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user