Index: src/main/jdbm/RecordManagerOptions.java =================================================================== RCS file: /cvsroot/jdbm/jdbm/src/main/jdbm/RecordManagerOptions.java,v retrieving revision 1.1 diff -u -r1.1 RecordManagerOptions.java --- src/main/jdbm/RecordManagerOptions.java 31 May 2002 06:33:20 -0000 1.1 +++ src/main/jdbm/RecordManagerOptions.java 9 Nov 2004 11:59:09 -0000 @@ -48,6 +48,8 @@ package jdbm; +import jdbm.recman.TransactionManager; + /** * Standard options for RecordManager. * @@ -84,6 +86,28 @@ /** + * Loosen DURABILITY feature to achieve better commit performance. + * (The option have no effect if {@link #DISABLE_TRANSACTIONS} is set). + * If NO_DURABILITY option is enabled (set to 'true'), + * the JDBM will "sync" the database file only when flushing the log file. + * This will allow the filesystem to cache the data which is written at transaction commit, + * but the database will no longer be DURABLE: commited transactions data + * may get lost after a system failure. + * @see #TRANSACTIONS_IN_LOG + */ + public static final String NO_DURABILITY = "jdbm.noDurability"; + + + /** + * The maximum number of transactions to record in + * the log (and keep in memory) before the log is + * synchronized with the main database file. + * @see TransactionManager#setMaximumTransactionsInLog + */ + public static final String TRANSACTIONS_IN_LOG = "jdbm.transactionsInLog"; + + + /** * Cache type. */ public static final String CACHE_TYPE = "jdbm.cache.type"; Index: src/main/jdbm/recman/Provider.java =================================================================== RCS file: /cvsroot/jdbm/jdbm/src/main/jdbm/recman/Provider.java,v retrieving revision 1.2 diff -u -r1.2 Provider.java --- src/main/jdbm/recman/Provider.java 6 Aug 2002 05:33:00 -0000 1.2 +++ src/main/jdbm/recman/Provider.java 9 Nov 2004 11:59:09 -0000 @@ -84,6 +84,7 @@ { RecordManager recman; String value; + int maxTxns; int cacheSize; recman = new BaseRecordManager( name ); @@ -93,6 +94,16 @@ ( (BaseRecordManager) recman ).disableTransactions(); } + value = options.getProperty( RecordManagerOptions.NO_DURABILITY, "false" ); + if ( value.equalsIgnoreCase( "TRUE" ) ) { + ( (BaseRecordManager) recman ).getTransactionManager().setDurability( false ); + } + + value = options.getProperty( RecordManagerOptions.TRANSACTIONS_IN_LOG ); + if ( null != value && ( maxTxns = Integer.parseInt( value ) ) > 0 ) { + ( (BaseRecordManager) recman ).getTransactionManager().setMaximumTransactionsInLog( maxTxns ); + } + value = options.getProperty( RecordManagerOptions.CACHE_SIZE, "1000" ); cacheSize = Integer.parseInt( value ); Index: src/main/jdbm/recman/TransactionManager.java =================================================================== RCS file: /cvsroot/jdbm/jdbm/src/main/jdbm/recman/TransactionManager.java,v retrieving revision 1.6 diff -u -r1.6 TransactionManager.java --- src/main/jdbm/recman/TransactionManager.java 7 Aug 2003 00:00:56 -0000 1.6 +++ src/main/jdbm/recman/TransactionManager.java 9 Nov 2004 11:59:09 -0000 @@ -89,6 +89,8 @@ private ArrayList[] txns = new ArrayList[DEFAULT_TXNS_IN_LOG]; private int curTxn = -1; + private boolean _durability = true; + /** Extension of a log file. */ static final String extension = ".lg"; @@ -143,7 +145,14 @@ txns = new ArrayList[ maxTxns ]; } - + /** + * Whether to sync the log on every commit (if 'true') + * or only before data file modifications (if 'false'). + */ + public void setDurability( boolean on ){ + _durability = on; + } + /** Builds logfile name */ private String makeLogName() { return owner.getFileName() + extension; @@ -206,6 +215,7 @@ } FileInputStream fis = new FileInputStream(logFile); + try{ ObjectInputStream ois = new ObjectInputStream(fis); try { @@ -239,6 +249,7 @@ } } owner.sync(); + }finally{ fis.close(); } logFile.delete(); } @@ -307,7 +318,7 @@ */ void commit() throws IOException { oos.writeObject(txns[curTxn]); - sync(); + if( _durability ) sync(); else flush(); // set clean flag to indicate blocks have been written to log setClean(txns[curTxn]); @@ -317,10 +328,15 @@ oos = new ObjectOutputStream(fos); } + /** Flushes, but does not syncs. */ + private void flush() throws IOException { + oos.flush(); + fos.flush(); + } + /** Flushes and syncs */ private void sync() throws IOException { - oos.flush(); - fos.flush(); + flush(); fos.getFD().sync(); }