From: Sasa M. <sa...@us...> - 2004-05-20 10:34:09
|
Update of /cvsroot/jrobin/src/org/jrobin/core In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10576/org/jrobin/core Added Files: RrdAllocator.java RrdBackend.java RrdBackendFactory.java RrdCacher.java RrdFileBackend.java RrdFileBackendFactory.java RrdMemoryBackend.java RrdMemoryBackendFactory.java RrdNioBackend.java RrdNioBackendFactory.java Log Message: Major core package redesign --- NEW FILE: RrdCacher.java --- /* ============================================================ * JRobin : Pure java implementation of RRDTool's functionality * ============================================================ * * Project Info: http://www.jrobin.org * Project Lead: Sasa Markovic (sa...@jr...); * * (C) Copyright 2003, by Sasa Markovic. * * Developers: Sasa Markovic (sa...@jr...) * Arne Vandamme (cob...@jr...) * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package org.jrobin.core; class RrdCacher { private Object cache = null; boolean setInt(int value) { if(isCached(value)) { return false; } else { cache = new Integer(value); return true; } } boolean setLong(long value) { if(isCached(value)) { return false; } else { cache = new Long(value); return true; } } boolean setDouble(double value) { if(isCached(value)) { return false; } else { cache = new Double(value); return true; } } boolean setString(String value) { if(isCached(value)) { return false; } else { cache = value; return true; } } boolean isEmpty() { return cache == null; } int getInt() { return ((Integer) cache).intValue(); } long getLong() { return ((Long) cache).longValue(); } double getDouble() { return ((Double) cache).doubleValue(); } String getString() { return (String) cache; } private boolean isCached(int value) { return cache != null && getInt() == value; } private boolean isCached(long value) { return cache != null && getLong() == value; } private boolean isCached(double value) { return cache != null && getDouble() == value; } private boolean isCached(String value) { return cache != null && getString().equals(value); } } --- NEW FILE: RrdBackend.java --- /* ============================================================ * JRobin : Pure java implementation of RRDTool's functionality * ============================================================ * * Project Info: http://www.jrobin.org * Project Lead: Sasa Markovic (sa...@jr...); * * (C) Copyright 2003, by Sasa Markovic. * * Developers: Sasa Markovic (sa...@jr...) * Arne Vandamme (cob...@jr...) * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package org.jrobin.core; import java.io.IOException; /** * Base implementation class for all backend classes. Each Round Robin Database object * ({@link RrdDb} object) is backed with a single RrdBackend object which performs * actual I/O operations on the underlying storage. JRobin supports * three different bakcends out of the box:</p> * <ul> * <li>{@link RrdFileBackend}: objects of this class are created from the * {@link RrdFileBackendFactory} class. This is the default backend used in all * JRobin releases. It uses java.io.* package and RandomAccessFile class to store * RRD data in files on the disk. * * <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 * {@link RrdMemoryBackendFactory} class. This backend stores all data in memory. Once * JVM exits, all data gets lost. The backend is extremely fast and memory hungry. * </ul> * * To create your own backend in order to provide some custom type of RRD storage, * you should do the following:</p> * * <ul> * <li>Create your custom RrdBackend class (RrdCustomBackend, for example) * by extending RrdBackend class. You have to implement all abstract methods defined * in the base class. * * <li>Create your custom RrdBackendFactory class (RrdCustomBackendFactory, * for example) by extending RrdBackendFactory class. You have to implement all * abstract methods defined in the base class. Your custom factory class will actually * create custom backend objects when necessary. * * <li>Create instance of your custom RrdBackendFactory and register it as a regular * factory available to JRobin framework. See javadoc for {@link RrdBackendFactory} to * find out how to do this * </ul> * */ public abstract class RrdBackend { private String path; /** * Creates backend for a RRD storage with the given path. * @param path String identifying RRD storage. For files on the disk, this * argument should represent file path. Other storage types might interpret * this argument differently. */ protected RrdBackend(String path) { this.path = path; } /** * Returns path to the storage. * @return Storage path */ public String getPath() { return path; } /** * Writes an array of bytes to the underlying storage starting from the given * storage offset. * @param offset Storage offset. * @param b Array of bytes that should be copied to the underlying storage * @throws IOException Thrown in case of I/O error */ protected abstract void write(long offset, byte[] b) throws IOException; /** * Reads an array of bytes from the underlying storage starting from the given * storage offset. * @param offset Storage offset. * @param b Array which receives bytes from the underlying storage * @throws IOException Thrown in case of I/O error */ protected abstract void read(long offset, byte[] b) throws IOException; /** * Reads all RRD bytes from the underlying storage * @return RRD bytes * @throws IOException Thrown in case of I/O error */ public final byte[] readAll() throws IOException { byte[] b = new byte[(int) getLength()]; read(0, b); return b; } /** * Returns the number of RRD bytes in the underlying storage. * @return Number of RRD bytes in the storage. * @throws IOException Thrown in case of I/O error. */ public abstract long getLength() throws IOException; /** * Sets the number of bytes in the underlying RRD storage. * This method is called only once, immediately after a new RRD storage gets created. * @param length Length of the underlying RRD storage in bytes. * @throws IOException Thrown in case of I/O error. */ protected abstract void setLength(long length) throws IOException; /** * Closes the storage. * @throws IOException Thrown in case of I/O error */ public abstract void close() throws IOException; final void writeInt(long offset, int value) throws IOException { write(offset, getIntBytes(value)); } final void writeLong(long offset, long value) throws IOException { write(offset, getLongBytes(value)); } final void writeDouble(long offset, double value) throws IOException { write(offset, getDoubleBytes(value)); } final void writeDouble(long offset, double value, int count) throws IOException { byte[] b = getDoubleBytes(value); byte[] image = new byte[8 * count]; for(int i = 0, k = 0; i < count; i++) { image[k++] = b[0]; image[k++] = b[1]; image[k++] = b[2]; image[k++] = b[3]; image[k++] = b[4]; image[k++] = b[5]; image[k++] = b[6]; image[k++] = b[7]; } write(offset, image); image = null; } final void writeDouble(long offset, double[] values) throws IOException { int count = values.length; byte[] image = new byte[8 * count]; for(int i = 0, k = 0; i < count; i++) { byte[] b = getDoubleBytes(values[i]); image[k++] = b[0]; image[k++] = b[1]; image[k++] = b[2]; image[k++] = b[3]; image[k++] = b[4]; image[k++] = b[5]; image[k++] = b[6]; image[k++] = b[7]; } write(offset, image); image = null; } final void writeString(long offset, String value) throws IOException { value = value.trim(); byte[] b = new byte[RrdPrimitive.STRING_LENGTH * 2]; for(int i = 0, k = 0; i < RrdPrimitive.STRING_LENGTH; i++) { char c = (i < value.length())? value.charAt(i): ' '; byte[] cb = getCharBytes(c); b[k++] = cb[0]; b[k++] = cb[1]; } write(offset, b); } final int readInt(long offset) throws IOException { byte[] b = new byte[4]; read(offset, b); return getInt(b); } final long readLong(long offset) throws IOException { byte[] b = new byte[8]; read(offset, b); return getLong(b); } final double readDouble(long offset) throws IOException { byte[] b = new byte[8]; read(offset, b); return getDouble(b); } final double[] readDouble(long offset, int count) throws IOException { int byteCount = 8 * count; byte[] image = new byte[byteCount]; read(offset, image); double[] values = new double[count]; for(int i = 0, k = -1; i < count; i++) { byte[] b = new byte[] { image[++k], image[++k], image[++k], image[++k], image[++k], image[++k], image[++k], image[++k] }; values[i] = getDouble(b); } image = null; return values; } final String readString(long offset) throws IOException { byte[] b = new byte[RrdPrimitive.STRING_LENGTH * 2]; char[] c = new char[RrdPrimitive.STRING_LENGTH]; read(offset, b); for(int i = 0, k = -1; i < RrdPrimitive.STRING_LENGTH; i++) { byte[] cb = new byte[] { b[++k], b[++k] }; c[i] = getChar(cb); } return new String(c).trim(); } // static helper methods private final static byte[] getIntBytes(int value) { byte[] b = new byte[4]; b[0] = (byte)((value >>> 24) & 0xFF); b[1] = (byte)((value >>> 16) & 0xFF); b[2] = (byte)((value >>> 8) & 0xFF); b[3] = (byte)((value >>> 0) & 0xFF); return b; } private final static byte[] getLongBytes(long value) { byte[] b = new byte[8]; b[0] = (byte)((int)(value >>> 56) & 0xFF); b[1] = (byte)((int)(value >>> 48) & 0xFF); b[2] = (byte)((int)(value >>> 40) & 0xFF); b[3] = (byte)((int)(value >>> 32) & 0xFF); b[4] = (byte)((int)(value >>> 24) & 0xFF); b[5] = (byte)((int)(value >>> 16) & 0xFF); b[6] = (byte)((int)(value >>> 8) & 0xFF); b[7] = (byte)((int)(value >>> 0) & 0xFF); return b; } private final static byte[] getCharBytes(char value) { byte[] b = new byte[2]; b[0] = (byte)((value >>> 8) & 0xFF); b[1] = (byte)((value >>> 0) & 0xFF); return b; } private final static byte[] getDoubleBytes(double value) { byte[] bytes = getLongBytes(Double.doubleToLongBits(value)); return bytes; } private final static int getInt(byte[] b) { assert b.length == 4: "Invalid number of bytes for integer conversion"; return ((b[0] << 24) & 0xFF000000) + ((b[1] << 16) & 0x00FF0000) + ((b[2] << 8) & 0x0000FF00) + ((b[3] << 0) & 0x000000FF); } private final static long getLong(byte[] b) { assert b.length == 8: "Invalid number of bytes for long conversion"; int high = getInt(new byte[] { b[0], b[1], b[2], b[3] }); int low = getInt(new byte[] { b[4], b[5], b[6], b[7] }); long value = ((long)(high) << 32) + (low & 0xFFFFFFFFL); return value; } private final static char getChar(byte[] b) { assert b.length == 2: "Invalid number of bytes for char conversion"; return (char)(((b[0] << 8) & 0x0000FF00) + ((b[1] << 0) & 0x000000FF)); } private final static double getDouble(byte[] b) { assert b.length == 8: "Invalid number of bytes for double conversion"; return Double.longBitsToDouble(getLong(b)); } } --- NEW FILE: RrdNioBackend.java --- /* ============================================================ * JRobin : Pure java implementation of RRDTool's functionality * ============================================================ * * Project Info: http://www.jrobin.org * Project Lead: Sasa Markovic (sa...@jr...); * * (C) Copyright 2003, by Sasa Markovic. * * Developers: Sasa Markovic (sa...@jr...) * Arne Vandamme (cob...@jr...) * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package org.jrobin.core; import java.io.IOException; import java.nio.channels.FileChannel; import java.nio.MappedByteBuffer; /** * JRobin backend which is used to store RRD data to ordinary files on the disk * by using java.nio.* package. */ 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()); } /** * Sets length of the underlying RRD file. This method is called only once, immediately * after a new RRD file gets created. * @param length Length of the RRD file * @throws IOException Thrown in case of I/O error. */ protected void setLength(long length) throws IOException { super.setLength(length); byteBuffer = file.getChannel().map(mapMode, 0, length); } /** * Writes bytes to the underlying RRD file on the disk * @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); } /** * Reads a number of bytes from the RRD file on the disk * @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); } /** * Closes the underlying RRD file. * @throws IOException Thrown in case of I/O error */ public void close() throws IOException { byteBuffer.force(); super.close(); } } --- NEW FILE: RrdMemoryBackendFactory.java --- /* ============================================================ * JRobin : Pure java implementation of RRDTool's functionality * ============================================================ * * Project Info: http://www.jrobin.org * Project Lead: Sasa Markovic (sa...@jr...); * * (C) Copyright 2003, by Sasa Markovic. * * Developers: Sasa Markovic (sa...@jr...) * Arne Vandamme (cob...@jr...) * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package org.jrobin.core; import java.io.IOException; import java.util.HashMap; /** * Factory class which creates actual {@link RrdMemoryBackend} objects. */ public class RrdMemoryBackendFactory extends RrdBackendFactory { /** factory name, "MEMORY" */ public static final String NAME = "MEMORY"; private HashMap backends = new HashMap(); /** * Creates RrdMemoryBackend object. * @param id Since this backend holds all data in memory, this argument is interpreted * as an ID for this memory-based storage. * @param readOnly This parameter is ignored * @param lockMode This parameter is ignored * @return RrdMemoryBackend object which handles all I/O operations * @throws IOException Thrown in case of I/O error. */ protected synchronized RrdBackend open(String id, boolean readOnly, int lockMode) throws IOException { RrdMemoryBackend backend; if(backends.containsKey(id)) { backend = (RrdMemoryBackend) backends.get(id); } else { backend = new RrdMemoryBackend(id); backends.put(id, backend); } return backend; } /** * Method to determine if a memory storage with the given ID already exists. * @param id Memory storage ID. * @return True, if such storage exists, false otherwise. */ protected synchronized boolean exists(String id) { return backends.containsKey(id); } /** * Removes the storage with the given ID from the memory. * @param id Storage ID * @return True, if the storage with the given ID is deleted, false otherwise. */ protected boolean delete(String id) { if(backends.containsKey(id)) { backends.remove(id); return true; } else { return false; } } /** * Returns the name of this factory. * @return Factory name (equals to "MEMORY"). */ protected String getFactoryName() { return NAME; } } --- NEW FILE: RrdBackendFactory.java --- /* ============================================================ * JRobin : Pure java implementation of RRDTool's functionality * ============================================================ * * Project Info: http://www.jrobin.org * Project Lead: Sasa Markovic (sa...@jr...); * * (C) Copyright 2003, by Sasa Markovic. * * Developers: Sasa Markovic (sa...@jr...) * Arne Vandamme (cob...@jr...) * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package org.jrobin.core; import java.util.HashMap; import java.io.IOException; /** * Base (abstract) backend factory class which holds references to all concrete * backend factories and defines abstract methods which must be implemented in * all concrete factory implementations.<p> * * Factory classes are used to create concrete {@link RrdBackend} implementations. * Each factory creates unlimited number of specific backend objects. * * JRobin supports three different backend types (backend factories) out of the box:<p> * <ul> * <li>{@link RrdFileBackend}: objects of this class are created from the * {@link RrdFileBackendFactory} class. This is the default backend used in all * JRobin releases. It uses java.io.* package and RandomAccessFile class to store * RRD data in files on the disk. * * <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 * {@link RrdMemoryBackendFactory} class. This backend stores all data in memory. Once * JVM exits, all data gets lost. The backend is extremely fast and memory hungry. * </ul> * * Each backend factory is identifed by its {@link #getFactoryName() name}. Constructors * are provided in the {@link RrdDb} class to create RrdDb objects (RRD databases) * backed with a specific backend.<p> * * See javadoc for {@link RrdBackend} to find out how to create your custom backends. */ public abstract class RrdBackendFactory { private static final HashMap factories = new HashMap(); private static RrdBackendFactory defaultFactory; static { try { RrdFileBackendFactory fileFactory = new RrdFileBackendFactory(); registerFactory(fileFactory); RrdMemoryBackendFactory memoryFactory = new RrdMemoryBackendFactory(); registerFactory(memoryFactory); RrdNioBackendFactory nioFactory = new RrdNioBackendFactory(); registerFactory(nioFactory); // Here is the default backend factory defaultFactory = fileFactory; } catch (RrdException e) { throw new RuntimeException("FATAL: Cannot register RRD backend factories: " + e); } } /** * Returns backend factory for the given backend factory name. * @param name Backend factory name. Initially supported names are:<p> * <ul> * <li><b>FILE</b>: Default factory which creates backends based on the * java.io.* package. RRD data is stored in files on the disk * <li><b>NIO</b>: Factory which creates backends based on the * java.nio.* package. RRD data is stored in files on the disk * <li><b>MEMORY</b>: Factory which creates memory-oriented backends. * RRD data is stored in memory, it gets lost as soon as JVM exits. * </ul> * @return Backend factory for the given factory name * @throws RrdException Thrown if no factory with the given name * is available. */ public static synchronized RrdBackendFactory getFactory(String name) throws RrdException { RrdBackendFactory factory = (RrdBackendFactory) factories.get(name); if(factory != null) { return factory; } else { throw new RrdException("No backend factory found with the name specified [" + name + "]"); } } /** * Registers new (custom) backend factory within the JRobin framework. * @param factory Factory to be registered * @throws RrdException Thrown if the name of the specified factory is already * used. */ public static synchronized void registerFactory(RrdBackendFactory factory) throws RrdException { String name = factory.getFactoryName(); if(!factories.containsKey(name)) { factories.put(name, factory); } else { throw new RrdException("Backend factory of this name2 (" + name + ") already exists and cannot be registered"); } } /** * Returns the defaul backend factory. This factory is used to construct * {@link RrdDb} objects if no factory is specified in the RrdDb constructor. * @return Default backend factory. */ public static RrdBackendFactory getDefaultFactory() { return defaultFactory; } /** * Creates RrdBackend object for the given storage path. * @param path Storage path * @param readOnly True, if the storage should be accessed in read/only mode. * False otherwise. * @param lockMode One of the following constants: {@link RrdDb.NO_LOCKS}, * {@link RrdDb.EXCEPTION_IF_LOCKED} or {@link RrdDb.WAIT_IF_LOCKED}. * @return Backend object which handles all I/O operations for the given storage path * @throws IOException Thrown in case of I/O error. */ protected abstract RrdBackend open(String path, boolean readOnly, int lockMode) throws IOException; /** * Method to determine if a storage with the given path already exists. * @param path Storage path * @return True, if such storage exists, false otherwise. */ protected abstract boolean exists(String path); /** * Releases all system resources associated with the storage with the given path. * If the storage represents a file on the disk, the file will be removed. * If the storage represents a section in memory, the memory will be released. * @param path Storage path * @return true, if all resources are released without a problem, false otherwise. */ protected abstract boolean delete(String path); /** * Returns the name (primary ID) for the factory. * @return Name of the factory. */ protected abstract String getFactoryName(); } --- NEW FILE: RrdFileBackend.java --- /* ============================================================ * JRobin : Pure java implementation of RRDTool's functionality * ============================================================ * * Project Info: http://www.jrobin.org * Project Lead: Sasa Markovic (sa...@jr...); * * (C) Copyright 2003, by Sasa Markovic. * * Developers: Sasa Markovic (sa...@jr...) * Arne Vandamme (cob...@jr...) * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package org.jrobin.core; import java.io.IOException; import java.io.RandomAccessFile; import java.io.File; import java.nio.channels.FileChannel; import java.nio.channels.FileLock; /** * Default JRobin backend which is used to store RRD data to ordinary files on the disk.<p> * * This backend is based on the RandomAccessFile class (java.io.* package). */ public class RrdFileBackend extends RrdBackend { static final long LOCK_DELAY = 100; // 0.1sec protected RandomAccessFile file; protected FileLock fileLock; RrdFileBackend(String path, boolean readOnly, int lockMode) throws IOException { super(path); file = new RandomAccessFile(path, readOnly? "r": "rw"); lockFile(lockMode); } private void lockFile(int lockMode) throws IOException { if(lockMode == RrdDb.WAIT_IF_LOCKED || lockMode == RrdDb.EXCEPTION_IF_LOCKED) { FileChannel fileChannel = file.getChannel(); do { fileLock = fileChannel.tryLock(); if(fileLock == null) { // could not obtain lock if(lockMode == RrdDb.WAIT_IF_LOCKED) { // wait a little, than try again try { Thread.sleep(LOCK_DELAY); } catch (InterruptedException e) { // NOP } } else { throw new IOException("Access denied. " + "File [" + getPath() + "] already locked"); } } } while(fileLock == null); } } /** * Closes the underlying RRD file. * @throws IOException Thrown in case of I/O error */ public void close() throws IOException { unlockFile(); file.close(); } private void unlockFile() throws IOException { if(fileLock != null) { fileLock.release(); fileLock = null; } } /** * Closes the underlying RRD file if not already closed * @throws IOException Thrown in case of I/O error */ protected void finalize() throws IOException { close(); } /** * Returns canonical path to the file on the disk. * @param path File path * @return Canonical file path * @throws IOException Thrown in case of I/O error */ public static String getCanonicalPath(String path) throws IOException { return new File(path).getCanonicalPath(); } /** * Returns canonical path to the file on the disk. * @return Canonical file path * @throws IOException Thrown in case of I/O error */ public String getCanonicalPath() throws IOException { return RrdFileBackend.getCanonicalPath(getPath()); } /** * Writes bytes to the underlying RRD file on the disk * @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 { file.seek(offset); file.write(b); } /** * Reads a number of bytes from the RRD file on the disk * @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 { file.seek(offset); if(file.read(b) != b.length) { throw new IOException("Not enough bytes available in file " + getPath()); } } /** * Returns RRD file length. * @return File length. * @throws IOException Thrown in case of I/O error. */ public long getLength() throws IOException { return file.length(); } /** * Sets length of the underlying RRD file. This method is called only once, immediately * after a new RRD file gets created. * @param length Length of the RRD file * @throws IOException Thrown in case of I/O error. */ protected void setLength(long length) throws IOException { file.setLength(length); } } --- NEW FILE: RrdFileBackendFactory.java --- /* ============================================================ * JRobin : Pure java implementation of RRDTool's functionality * ============================================================ * * Project Info: http://www.jrobin.org * Project Lead: Sasa Markovic (sa...@jr...); * * (C) Copyright 2003, by Sasa Markovic. * * Developers: Sasa Markovic (sa...@jr...) * Arne Vandamme (cob...@jr...) * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package org.jrobin.core; import java.io.IOException; import java.io.File; /** * Factory class which creates actual {@link RrdFileBackend} objects. This is the default * backend factory in JRobin. */ public class RrdFileBackendFactory extends RrdBackendFactory { /** factory name, "FILE" */ public static final String NAME = "FILE"; /** * Creates RrdFileBackend object for the given file path. * @param path File path * @param readOnly True, if the file should be accessed in read/only mode. * False otherwise. * @param lockMode One of the following constants: {@link RrdDb.NO_LOCKS}, * {@link RrdDb.EXCEPTION_IF_LOCKED} or {@link RrdDb.WAIT_IF_LOCKED}. * @return RrdFileBackend object which handles all I/O operations for the given file path * @throws IOException Thrown in case of I/O error. */ protected RrdBackend open(String path, boolean readOnly, int lockMode) throws IOException { return new RrdFileBackend(path, readOnly, lockMode); } /** * Method to determine if a file with the given path already exists. * @param path File path * @return True, if such file exists, false otherwise. */ protected boolean exists(String path) { return new File(path).exists(); } /** * Removes the file from the disk. * @param path File path * @return True, if the file is deleted, false otherwise. */ protected boolean delete(String path) { return new File(path).delete(); } /** * Returns the name of this factory. * @return Factory name (equals to string "FILE") */ protected String getFactoryName() { return NAME; } } --- NEW FILE: RrdAllocator.java --- /* ============================================================ * JRobin : Pure java implementation of RRDTool's functionality * ============================================================ * * Project Info: http://www.jrobin.org * Project Lead: Sasa Markovic (sa...@jr...); * * (C) Copyright 2003, by Sasa Markovic. * * Developers: Sasa Markovic (sa...@jr...) * Arne Vandamme (cob...@jr...) * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package org.jrobin.core; import java.io.IOException; class RrdAllocator { private long allocationPointer = 0L; long allocate(long byteCount) throws IOException { long pointer = allocationPointer; allocationPointer += byteCount; return pointer; } } --- NEW FILE: RrdNioBackendFactory.java --- /* ============================================================ * JRobin : Pure java implementation of RRDTool's functionality * ============================================================ * * Project Info: http://www.jrobin.org * Project Lead: Sasa Markovic (sa...@jr...); * * (C) Copyright 2003, by Sasa Markovic. * * Developers: Sasa Markovic (sa...@jr...) * Arne Vandamme (cob...@jr...) * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package org.jrobin.core; import java.io.IOException; /** * Factory class which creates actual {@link RrdNioBackend} objects. */ public class RrdNioBackendFactory extends RrdFileBackendFactory{ /** factory name, "NIO" */ public static final String NAME = "NIO"; /** * Creates RrdNioBackend object for the given file path. * @param path File path * @param readOnly True, if the file should be accessed in read/only mode. * False otherwise. * @param lockMode One of the following constants: {@link RrdDb.NO_LOCKS}, * {@link RrdDb.EXCEPTION_IF_LOCKED} or {@link RrdDb.WAIT_IF_LOCKED}. * @return RrdNioBackend object which handles all I/O operations for the given file path * @throws IOException Thrown in case of I/O error. */ protected RrdBackend open(String path, boolean readOnly, int lockMode) throws IOException { return new RrdNioBackend(path, readOnly, lockMode); } /** * Returns the name of this factory. * @return Factory name (equals to string "NIO") */ protected String getFactoryName() { return NAME; } } --- NEW FILE: RrdMemoryBackend.java --- /* ============================================================ * JRobin : Pure java implementation of RRDTool's functionality * ============================================================ * * Project Info: http://www.jrobin.org * Project Lead: Sasa Markovic (sa...@jr...); * * (C) Copyright 2003, by Sasa Markovic. * * Developers: Sasa Markovic (sa...@jr...) * Arne Vandamme (cob...@jr...) * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package org.jrobin.core; import java.io.IOException; /** * Backend which is used to store all RRD bytes in memory.<p> */ public class RrdMemoryBackend extends RrdBackend { private byte[] buffer = new byte[0]; RrdMemoryBackend(String path) { super(path); } protected void write(long offset, byte[] b) throws IOException { int pos = (int) offset; for(int i = 0; i < b.length; i++) { buffer[pos++] = b[i]; } } protected void read(long offset, byte[] b) throws IOException { int pos = (int) offset; if(pos + b.length <= buffer.length) { for(int i = 0; i < b.length; i++) { b[i] = buffer[pos++]; } } else { throw new IOException("Not enough bytes available in memory " + getPath()); } } /** * Returns the number of RRD bytes held in memory. * @return Number of all RRD bytes. */ public long getLength() { return buffer.length; } /** * Reserves a memory section as a RRD storage. * @param newLength Number of bytes held in memory. * @throws IOException Thrown in case of I/O error. */ protected void setLength(long newLength) throws IOException { if(newLength > Integer.MAX_VALUE) { throw new IOException("Cannot create this big memory backed RRD"); } buffer = new byte[(int) newLength]; } /** * This method is required by the base class definition, but has no effect at all. */ public void close() { // NOP } } |