aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJames Ahlborn <jtahlborn@yahoo.com>2007-04-25 20:09:52 +0000
committerJames Ahlborn <jtahlborn@yahoo.com>2007-04-25 20:09:52 +0000
commit369bac8704527ccee22f8d843c203439cadfa6f3 (patch)
tree26b2999424f3a3a918614eb4661226646b1a3e47 /src
parent5ed321fc055600aa240f10ff2e1a5873a68e2c49 (diff)
downloadjackcess-369bac8704527ccee22f8d843c203439cadfa6f3.tar.gz
jackcess-369bac8704527ccee22f8d843c203439cadfa6f3.zip
add autosync option
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@141 f203690c-595d-4dc9-a70b-905162fa7fd2
Diffstat (limited to 'src')
-rw-r--r--src/java/com/healthmarketscience/jackcess/Database.java58
-rw-r--r--src/java/com/healthmarketscience/jackcess/PageChannel.java11
-rw-r--r--src/java/com/healthmarketscience/jackcess/Table.java2
3 files changed, 63 insertions, 8 deletions
diff --git a/src/java/com/healthmarketscience/jackcess/Database.java b/src/java/com/healthmarketscience/jackcess/Database.java
index 43bee10..3468b4f 100644
--- a/src/java/com/healthmarketscience/jackcess/Database.java
+++ b/src/java/com/healthmarketscience/jackcess/Database.java
@@ -74,6 +74,10 @@ public class Database
SID[1] = (byte) 0x33;
}
+ /** default value for the auto-sync value ({@code true}). this is slower,
+ but leaves more chance of a useable database in the face of failures. */
+ public static final boolean DEFAULT_AUTO_SYNC = true;
+
/** Batch commit size for copying other result sets into this database */
private static final int COPY_TABLE_BATCH_SIZE = 200;
@@ -188,7 +192,8 @@ public class Database
/**
* Open an existing Database. If the existing file is not writeable, the
- * file will be opened read-only.
+ * file will be opened read-only. Auto-syncing is enabled for the returned
+ * Database.
* @param mdbFile File containing the database
*/
public static Database open(File mdbFile) throws IOException {
@@ -198,6 +203,7 @@ public class Database
/**
* Open an existing Database. If the existing file is not writeable or the
* readOnly flag is <code>true</code>, the file will be opened read-only.
+ * Auto-syncing is enabled for the returned Database.
* @param mdbFile File containing the database
* @param readOnly iff <code>true</code>, force opening file in read-only
* mode
@@ -205,11 +211,33 @@ public class Database
public static Database open(File mdbFile, boolean readOnly)
throws IOException
{
+ return open(mdbFile, readOnly, DEFAULT_AUTO_SYNC);
+ }
+
+ /**
+ * Open an existing Database. If the existing file is not writeable or the
+ * readOnly flag is <code>true</code>, the file will be opened read-only.
+ * @param mdbFile File containing the database
+ * @param readOnly iff <code>true</code>, force opening file in read-only
+ * mode
+ * @param autoSync whether or not to enable auto-syncing on write. if
+ * {@code true}, writes will be immediately flushed to disk.
+ * This leaves the database in a (fairly) consistent state
+ * on each write, but can be very inefficient for many
+ * updates. if {@code false}, flushing to disk happens at
+ * the jvm's leisure, which can be much faster, but may
+ * leave the database in an inconsistent state if failures
+ * are encountered during writing.
+ */
+ public static Database open(File mdbFile, boolean readOnly, boolean autoSync)
+ throws IOException
+ {
if(!mdbFile.exists() || !mdbFile.canRead()) {
throw new FileNotFoundException("given file does not exist: " + mdbFile);
}
return new Database(openChannel(mdbFile,
- (!mdbFile.canWrite() || readOnly)));
+ (!mdbFile.canWrite() || readOnly)),
+ autoSync);
}
/**
@@ -218,11 +246,30 @@ public class Database
* already exists, it will be overwritten.</b>
*/
public static Database create(File mdbFile) throws IOException {
+ return create(mdbFile, DEFAULT_AUTO_SYNC);
+ }
+
+ /**
+ * Create a new Database
+ * @param mdbFile Location to write the new database to. <b>If this file
+ * already exists, it will be overwritten.</b>
+ * @param autoSync whether or not to enable auto-syncing on write. if
+ * {@code true}, writes will be immediately flushed to disk.
+ * This leaves the database in a (fairly) consistent state
+ * on each write, but can be very inefficient for many
+ * updates. if {@code false}, flushing to disk happens at
+ * the jvm's leisure, which can be much faster, but may
+ * leave the database in an inconsistent state if failures
+ * are encountered during writing.
+ */
+ public static Database create(File mdbFile, boolean autoSync)
+ throws IOException
+ {
FileChannel channel = openChannel(mdbFile, false);
channel.transferFrom(Channels.newChannel(
Thread.currentThread().getContextClassLoader().getResourceAsStream(
EMPTY_MDB)), 0, (long) Integer.MAX_VALUE);
- return new Database(channel);
+ return new Database(channel, autoSync);
}
private static FileChannel openChannel(File mdbFile, boolean readOnly)
@@ -238,9 +285,10 @@ public class Database
* FileChannel instead of a ReadableByteChannel because we need to
* randomly jump around to various points in the file.
*/
- protected Database(FileChannel channel) throws IOException {
+ protected Database(FileChannel channel, boolean autoSync) throws IOException
+ {
_format = JetFormat.getFormat(channel);
- _pageChannel = new PageChannel(channel, _format);
+ _pageChannel = new PageChannel(channel, _format, autoSync);
_buffer = _pageChannel.createPageBuffer();
readSystemCatalog();
}
diff --git a/src/java/com/healthmarketscience/jackcess/PageChannel.java b/src/java/com/healthmarketscience/jackcess/PageChannel.java
index 3865394..69b9206 100644
--- a/src/java/com/healthmarketscience/jackcess/PageChannel.java
+++ b/src/java/com/healthmarketscience/jackcess/PageChannel.java
@@ -57,14 +57,19 @@ public class PageChannel implements Channel {
private JetFormat _format;
/** Tracks free pages in the database. */
private UsageMap _globalUsageMap;
+ /** whether or not to force all writes to disk immediately */
+ private boolean _autoSync;
/**
* @param channel Channel containing the database
* @param format Format of the database in the channel
*/
- public PageChannel(FileChannel channel, JetFormat format) throws IOException {
+ public PageChannel(FileChannel channel, JetFormat format, boolean autoSync)
+ throws IOException
+ {
_channel = channel;
_format = format;
+ _autoSync = autoSync;
//Null check only exists for unit tests. Channel should never normally be null.
if (channel != null) {
_globalUsageMap = UsageMap.read(this, PAGE_GLOBAL_USAGE_MAP, (byte) 0, format);
@@ -100,7 +105,9 @@ public class PageChannel implements Channel {
public void writePage(ByteBuffer page, int pageNumber) throws IOException {
page.rewind();
_channel.write(page, (long) pageNumber * (long) _format.PAGE_SIZE);
- _channel.force(true);
+ if(_autoSync) {
+ _channel.force(true);
+ }
}
/**
diff --git a/src/java/com/healthmarketscience/jackcess/Table.java b/src/java/com/healthmarketscience/jackcess/Table.java
index a0ed9a6..9b60071 100644
--- a/src/java/com/healthmarketscience/jackcess/Table.java
+++ b/src/java/com/healthmarketscience/jackcess/Table.java
@@ -112,7 +112,7 @@ public class Table
* Only used by unit tests
*/
Table() throws IOException {
- _pageChannel = new PageChannel(null, JetFormat.VERSION_4);
+ _pageChannel = new PageChannel(null, JetFormat.VERSION_4, true);
}
/**