From: Sasa M. <sa...@us...> - 2004-05-30 10:07:03
|
Update of /cvsroot/jrobin/src/org/jrobin/core In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23240/org/jrobin/core Modified Files: RrdBackend.java RrdDb.java RrdNioBackend.java RrdNioBackendFactory.java Log Message: greatly improved RrdNioBackend. By default RrdNioBackend is flushed to the disc every 60 seconds from a separate thread. Index: RrdBackend.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/core/RrdBackend.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** RrdBackend.java 28 May 2004 10:22:47 -0000 1.3 --- RrdBackend.java 30 May 2004 10:06:47 -0000 1.4 *************** *** 41,45 **** * <li>{@link RrdNioBackend}: objects of this class are created from the * {@link RrdNioBackendFactory} class. The backend uses java.io.* and java.nio.* ! * classes (mapped ByteBuffer) to store RRD data in files on the disk. * * <li>{@link RrdMemoryBackend}: objects of this class are created from the --- 41,47 ---- * <li>{@link RrdNioBackend}: objects of this class are created from the * {@link RrdNioBackendFactory} class. The backend uses java.io.* and java.nio.* ! * classes (mapped ByteBuffer) to store RRD data in files on the disk. This backend is fast, very fast, ! * but consumes a lot of memory (borrowed not from the JVM but from the underlying operating system ! * directly). * * <li>{@link RrdMemoryBackend}: objects of this class are created from the *************** *** 141,144 **** --- 143,181 ---- /** + * Method called by the framework immediatelly before RRD update operation starts. This method + * does nothing, but can be overriden in subclasses. + */ + protected void beforeUpdate() throws IOException { + } + + /** + * Method called by the framework immediatelly after RRD update operation is completed. This method + * does nothing, but can be overriden in subclasses. + */ + protected void afterUpdate() throws IOException { + } + + /** + * Method called by the framework immediatelly before RRD fetch operation starts. This method + * does nothing, but can be overriden in subclasses. + */ + protected void beforeFetch() throws IOException { + } + + /** + * Method called by the framework immediatelly after RRD fetch operation is completed. This method + * does nothing, but can be overriden in subclasses. + */ + protected void afterFetch() throws IOException { + } + + /** + * Method called by the framework immediatelly after RrdDb obejct is created. This method + * does nothing, but can be overriden in subclasses. + */ + protected void afterCreate() throws IOException { + } + + /** * This method forces all data cached in memory but not yet stored in the persistant * storage, to be stored in it. In the base class this method does nothing but Index: RrdNioBackend.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/core/RrdNioBackend.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** RrdNioBackend.java 28 May 2004 10:22:47 -0000 1.2 --- RrdNioBackend.java 30 May 2004 10:06:48 -0000 1.3 *************** *** 29,32 **** --- 29,34 ---- import java.nio.channels.FileChannel; import java.nio.MappedByteBuffer; + import java.util.TimerTask; + import java.util.Timer; /** *************** *** 35,45 **** */ public class RrdNioBackend extends RrdFileBackend { ! FileChannel.MapMode mapMode; MappedByteBuffer byteBuffer; ! RrdNioBackend(String path, boolean readOnly, int lockMode) throws IOException { super(path, readOnly, lockMode); ! mapMode = readOnly? FileChannel.MapMode.READ_ONLY: FileChannel.MapMode.READ_WRITE; ! byteBuffer = file.getChannel().map(mapMode, 0, getLength()); } --- 37,65 ---- */ public class RrdNioBackend extends RrdFileBackend { ! private int syncMode; MappedByteBuffer byteBuffer; ! private Timer syncTimer; ! ! RrdNioBackend(String path, boolean readOnly, int lockMode, int syncMode, int syncPeriod) ! throws IOException { super(path, readOnly, lockMode); ! this.syncMode = syncMode; ! FileChannel.MapMode mapMode = ! readOnly? FileChannel.MapMode.READ_ONLY: FileChannel.MapMode.READ_WRITE; ! this.byteBuffer = file.getChannel().map(mapMode, 0, getLength()); ! if(syncMode == RrdNioBackendFactory.SYNC_BACKGROUND && !readOnly) { ! createSyncTask(syncPeriod); ! } ! } ! ! private void createSyncTask(int syncPeriod) { ! TimerTask syncTask = new TimerTask() { ! public void run() { ! sync(); ! } ! }; ! syncTimer = new Timer(true); ! syncTimer.schedule(syncTask, syncPeriod * 1000L, syncPeriod * 1000L); } *************** *** 52,56 **** protected void setLength(long length) throws IOException { super.setLength(length); ! byteBuffer = file.getChannel().map(mapMode, 0, length); } --- 72,76 ---- protected void setLength(long length) throws IOException { super.setLength(length); ! byteBuffer = file.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, length); } *************** *** 59,67 **** * @param offset Starting file offset * @param b Bytes to be written. - * @throws IOException Thrown in case of I/O error */ ! protected void write(long offset, byte[] b) throws IOException { ! byteBuffer.position((int)offset); ! byteBuffer.put(b); } --- 79,88 ---- * @param offset Starting file offset * @param b Bytes to be written. */ ! protected void write(long offset, byte[] b) { ! synchronized(byteBuffer) { ! byteBuffer.position((int)offset); ! byteBuffer.put(b); ! } } *************** *** 70,78 **** * @param offset Starting file offset * @param b Buffer which receives bytes read from the file. - * @throws IOException Thrown in case of I/O error. */ ! protected void read(long offset, byte[] b) throws IOException { ! byteBuffer.position((int)offset); ! byteBuffer.get(b); } --- 91,100 ---- * @param offset Starting file offset * @param b Buffer which receives bytes read from the file. */ ! protected void read(long offset, byte[] b) { ! synchronized(byteBuffer) { ! byteBuffer.position((int)offset); ! byteBuffer.get(b); ! } } *************** *** 82,86 **** */ public void close() throws IOException { ! super.close(); } --- 104,111 ---- */ public void close() throws IOException { ! if(syncTimer != null) { ! syncTimer.cancel(); ! } ! super.close(); // calls sync() } *************** *** 90,99 **** * This method is automatically invoked when the {@link #close()} * method is called. In other words, you don't have to call sync() before you call close().<p> - * - * @throws IOException Thrown in case of I/O error */ ! protected void sync() throws IOException { ! byteBuffer.force(); } } --- 115,147 ---- * This method is automatically invoked when the {@link #close()} * method is called. In other words, you don't have to call sync() before you call close().<p> */ ! protected void sync() { ! synchronized(byteBuffer) { ! byteBuffer.force(); ! } ! } ! ! protected void beforeUpdate() { ! if(syncMode == RrdNioBackendFactory.SYNC_BEFOREUPDATE) { ! sync(); ! } } + protected void afterUpdate() { + if(syncMode == RrdNioBackendFactory.SYNC_AFTERUPDATE) { + sync(); + } + } + + protected void beforeFetch() { + if(syncMode == RrdNioBackendFactory.SYNC_BEFOREFETCH) { + sync(); + } + } + + protected void afterFetch() { + if(syncMode == RrdNioBackendFactory.SYNC_AFTERFETCH) { + sync(); + } + } } Index: RrdDb.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/core/RrdDb.java,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** RrdDb.java 28 May 2004 10:22:47 -0000 1.17 --- RrdDb.java 30 May 2004 10:06:47 -0000 1.18 *************** *** 178,181 **** --- 178,182 ---- archives[i] = new Archive(this, arcDefs[i]); } + backend.afterCreate(); } *************** *** 321,324 **** --- 322,326 ---- // XMLReader is a rather huge DOM tree, release memory ASAP reader = null; + backend.afterCreate(); } *************** *** 463,466 **** --- 465,469 ---- throw new RrdException("RRD already closed, cannot store this sample"); } + backend.beforeUpdate(); long newTime = sample.getTime(); long lastTime = header.getLastUpdateTime(); *************** *** 475,478 **** --- 478,482 ---- } header.setLastUpdateTime(newTime); + backend.afterUpdate(); } *************** *** 481,486 **** --- 485,492 ---- throw new RrdException("RRD already closed, cannot fetch data"); } + backend.beforeFetch(); Archive archive = findMatchingArchive(request); FetchPoint[] points = archive.fetch(request); + backend.afterFetch(); return points; } *************** *** 490,495 **** --- 496,503 ---- throw new RrdException("RRD already closed, cannot fetch data"); } + backend.beforeFetch(); Archive archive = findMatchingArchive(request); FetchData fetchData = archive.fetchData(request); + backend.afterFetch(); return fetchData; } *************** *** 909,912 **** --- 917,923 ---- * synchronizes all data in memory with the data in the persisant storage.<p> * + * When this method returns it is guaranteed that RRD data in the persistent storage is + * synchronized with the RrdDb data in memory.<p> + * * @throws IOException Thrown in case of I/O error */ *************** *** 915,917 **** --- 926,939 ---- } + /** + * Sets default backend factory to be used. This method is just an alias for + * {@link RrdBackendFactory#setDefaultFactory(java.lang.String)}.<p> + * @param factoryName Name of the backend factory to be set as default. + * @throws RrdException Thrown if invalid factory name is supplied, or not called + * before the first backend object (before the first RrdDb object) is created. + */ + public static void setDefaultFactory(String factoryName) throws RrdException { + RrdBackendFactory.setDefaultFactory(factoryName); + } + } Index: RrdNioBackendFactory.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/core/RrdNioBackendFactory.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** RrdNioBackendFactory.java 25 May 2004 11:35:58 -0000 1.2 --- RrdNioBackendFactory.java 30 May 2004 10:06:48 -0000 1.3 *************** *** 35,38 **** --- 35,112 ---- public static final String NAME = "NIO"; + /** See {@link #setSyncMode(int) for explanation } */ + public static final int SYNC_DEFAULT = 0; // will sync() only on close() + /** See {@link #setSyncMode(int) for explanation } */ + public static final int SYNC_BEFOREUPDATE = 1; + /** See {@link #setSyncMode(int) for explanation } */ + public static final int SYNC_AFTERUPDATE = 2; + /** See {@link #setSyncMode(int) for explanation } */ + public static final int SYNC_BEFOREFETCH = 3; + /** See {@link #setSyncMode(int) for explanation } */ + public static final int SYNC_AFTERFETCH = 4; + /** See {@link #setSyncMode(int) for explanation } */ + public static final int SYNC_BACKGROUND = 5; + /** See {@link #setSyncPeriod(int)} for explanation */ + public static final int DEFAULT_SYNC_PERIOD = 60; // seconds + + private static int syncMode = SYNC_BACKGROUND; + private static int syncPeriod = DEFAULT_SYNC_PERIOD; + + /** + * Returns the current synchronization mode between backend data in memory and data + * in the persistent storage (disk file). + * + * @return Integer representing current synchronization mode (SYNC_DEFAULT, + * SYNC_BEFOREUPDATE, SYNC_AFTERUPDATE, SYNC_BEFOREFETCH, SYNC_AFTERFETCH or + * SYNC_BACKGROUND). See {@link #setSyncMode(int)} for full explanation of these return values. + */ + public static int getSyncMode() { + return syncMode; + } + + /** + * Sets the current synchronization mode between backend data in memory (backend cache) and + * RRD data in the persistant storage (disk file).<p> + * @param syncMode Desired synchronization mode. Possible values are:<p> + * <ul> + * <li>SYNC_DEFAULT: synchronization will be performed only when {@link RrdDb#close()} + * is called (RRD file is closed) or when {@link RrdDb#sync()} method is called. + * <li>SYNC_BEFOREUPDATE: synchronization will be performed before each {@link Sample#update()} + * call (right before RRD file is about to be updated). + * <li>SYNC_AFTERUPDATE: synchronization will be performed after each {@link Sample#update()} + * call (right after RRD file is updated). + * <li>SYNC_BEFOREFETCH: synchronization will be performed before each + * {@link FetchRequest#fetchData()} call (right before data is about to be fetched from a RRD file, + * for example for graph creation) + * <li>SYNC_AFTERFETCH: synchronization will be performed after each + * {@link FetchRequest#fetchData()} call (right after data is fetched from a RRD file) + * <li>SYNC_BACKGROUND (<b>default</b>): synchronization will be performed automatically + * from a separate thread on a regular basis. Period of time between the two consecutive + * synchronizations can be controlled with {@link #setSyncPeriod(int)}. + * </ul> + */ + public static void setSyncMode(int syncMode) { + RrdNioBackendFactory.syncMode = syncMode; + } + + /** + * Returns time between two consecutive background synchronizations. If not changed via + * {@link #setSyncPeriod(int)} method call, defaults to DEFAULT_SYNC_PERIOD (60 seconds). + * See {@link #setSyncPeriod(int)} for more information. + * @return Time in seconds between consecutive background synchronizations. + */ + public static int getSyncPeriod() { + return syncPeriod; + } + + /** + * Sets time between consecutive background synchronizations. Method is effective only if + * synchronization mode is set to SYNC_BACKGROUND. + * @param syncPeriod Time in seconds between consecutive background synchronizations. + */ + public static void setSyncPeriod(int syncPeriod) { + RrdNioBackendFactory.syncPeriod = syncPeriod; + } + /** * Creates RrdNioBackend object for the given file path. *************** *** 46,50 **** */ protected RrdBackend open(String path, boolean readOnly, int lockMode) throws IOException { ! return new RrdNioBackend(path, readOnly, lockMode); } --- 120,124 ---- */ protected RrdBackend open(String path, boolean readOnly, int lockMode) throws IOException { ! return new RrdNioBackend(path, readOnly, lockMode, syncMode, syncPeriod); } |