diff options
author | James Ahlborn <jtahlborn@yahoo.com> | 2007-04-25 20:09:52 +0000 |
---|---|---|
committer | James Ahlborn <jtahlborn@yahoo.com> | 2007-04-25 20:09:52 +0000 |
commit | 369bac8704527ccee22f8d843c203439cadfa6f3 (patch) | |
tree | 26b2999424f3a3a918614eb4661226646b1a3e47 /src | |
parent | 5ed321fc055600aa240f10ff2e1a5873a68e2c49 (diff) | |
download | jackcess-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')
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); } /** |