You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by fr...@apache.org on 2002/01/12 17:55:43 UTC
cvs commit: jakarta-commons-sandbox/simplestore/src/java/org/apache/commons/simplestore StoreJanitorImpl.java StoreJanitor.java Store.java MRUMemoryStore.java JispStringKey.java JispFilesystemStore.java
froehlich 02/01/12 08:55:43
Added: simplestore/src/java/org/apache/commons/simplestore
StoreJanitorImpl.java StoreJanitor.java Store.java
MRUMemoryStore.java JispStringKey.java
JispFilesystemStore.java
Log:
inital commit of the simplestore components
Revision Changes Path
1.1 jakarta-commons-sandbox/simplestore/src/java/org/apache/commons/simplestore/StoreJanitorImpl.java
Index: StoreJanitorImpl.java
===================================================================
/*****************************************************************************
* Copyright (C) The Apache Software Foundation. All rights reserved. *
* ------------------------------------------------------------------------- *
* This software is published under the terms of the Apache Software License *
* version 1.1, a copy of which has been included with this distribution in *
* the LICENSE file. *
*****************************************************************************/
package org.apache.commons.simplestore;
import java.util.ArrayList;
import java.util.Iterator;
/**
* This class is a implentation of a StoreJanitor. Store classes
* can register to the StoreJanitor. When memory is too low,
* the StoreJanitor frees the registered caches until memory is normal.
*
* @author <a href="mailto:g-froehlich@gmx.de">Gerhard Froehlich</a>
*/
public class StoreJanitorImpl
implements StoreJanitor,
Runnable {
private int mFreeMemory = -1;
private int mHeapSize = -1;
private int mThreadInterval = -1;
private int mThreadPriority = -1;
private Runtime mJVM;
private ArrayList mStoreList;
private int mIndex = -1;
private static boolean mDoRun = false;
/**
* Initialize the StoreJanitorImpl.
*
* @param the Configuration of the application
* @exception ConfigurationException
*/
public void initialize() {
this.mJVM = Runtime.getRuntime();
this.mStoreList = new ArrayList();
}
public void start() {
mDoRun = true;
Thread checker = new Thread(this);
checker.setPriority(this.getThreadPriority());
checker.setDaemon(true);
checker.setName("checker");
checker.start();
}
public void stop() {
mDoRun = false;
}
/**
* The "checker" thread checks if memory is running low in the jvm.
*/
public void run() {
while (mDoRun) {
// amount of memory used is greater then heapsize
if (this.memoryLow()) {
this.freePhysicalMemory();
synchronized (this) {
while (this.memoryLow() && this.mStoreList.size() > 0) {
this.freeMemory();
}
this.resetIndex();
}
}
try {
Thread.currentThread().sleep(this.mThreadInterval * 1000);
} catch (InterruptedException ignore) {}
}
}
/**
* Method to check if memory is running low in the JVM.
*
* @return true if memory is low
*/
private boolean memoryLow() {
return this.mJVM.totalMemory() > this.getHeapsize() && this.mJVM.freeMemory() < this.getFreememory();
}
/**
* This method register the stores
*
* @param the store to be registered
*/
public void register(Store store) {
this.mStoreList.add(store);
}
/**
* This method unregister the stores
*
* @param the store to be unregistered
*/
public void unregister(Store store) {
this.mStoreList.remove(store);
}
/**
* This method return a java.util.Iterator of every registered stores
*
* @return a java.util.Iterator
*/
public Iterator iterator() {
return this.mStoreList.iterator();
}
/**
* Round Robin alghorithm for freeing the registerd caches.
*/
private void freeMemory() {
try {
if (this.mIndex < this.mStoreList.size()) {
if(this.mIndex == -1) {
((Store)this.mStoreList.get(0)).free();
this.mIndex = 0;
} else {
((Store)this.mStoreList.get(this.mIndex)).free();
this.mIndex = this.mIndex + 1;
}
} else {
this.resetIndex();
((Store)this.mStoreList.get(0)).free();
this.mIndex = 0;
}
this.freePhysicalMemory();
} catch(Exception e) {
e.printStackTrace();
}
}
/**
* This method forces the garbage collector
*/
private void freePhysicalMemory() {
this.mJVM.runFinalization();
this.mJVM.gc();
}
public int getFreememory() {
return mFreeMemory;
}
public void setFreeMemory(int _freememory) {
this.mFreeMemory = _freememory;
}
public int getHeapsize() {
return this.mHeapSize;
}
public void setHeapsize(int _heapsize) {
this.mHeapSize = _heapsize;
}
public int getThreadInterval() {
return this.mThreadInterval;
}
public void setThreadInterval(int _cleanupthreadinterval) {
this.mThreadInterval = _cleanupthreadinterval;
}
public int getThreadPriority() {
return this.mThreadPriority;
}
public void setThreadPriority(int _priority) {
this.mThreadPriority = _priority;
}
private void resetIndex() {
this.mIndex = -1;
}
}
1.1 jakarta-commons-sandbox/simplestore/src/java/org/apache/commons/simplestore/StoreJanitor.java
Index: StoreJanitor.java
===================================================================
/*****************************************************************************
* Copyright (C) The Apache Software Foundation. All rights reserved. *
* ------------------------------------------------------------------------- *
* This software is published under the terms of the Apache Software License *
* version 1.1, a copy of which has been included with this distribution in *
* the LICENSE file. *
*****************************************************************************/
package org.apache.commons.simplestore;
import java.util.Iterator;
/**
* Interface for the StoreJanitors
*
* @author <a href="mailto:g-froehlich@gmx.de">Gerhard Froehlich</a>
*/
public interface StoreJanitor {
/** register method for the stores */
void register(Store store);
/** unregister method for the stores */
void unregister(Store store);
/** get an iterator to list registered stores */
Iterator iterator();
}
1.1 jakarta-commons-sandbox/simplestore/src/java/org/apache/commons/simplestore/Store.java
Index: Store.java
===================================================================
/*****************************************************************************
* Copyright (C) The Apache Software Foundation. All rights reserved. *
* ------------------------------------------------------------------------- *
* This software is published under the terms of the Apache Software License *
* version 1.1, a copy of which has been included with this distribution in *
* the LICENSE file. *
*****************************************************************************/
package org.apache.commons.simplestore;
import java.io.IOException;
import java.util.Enumeration;
/**
* Interface for the Store implementations
*
* @author <a href="mailto:g-froehlich@gmx.de">Gerhard Froehlich</a>
*/
public interface Store {
/**
* Get the object associated to the given unique key.
*/
Object get(Object key);
/**
* Store the given object in a persistent state. It is up to the
* caller to ensure that the key has a persistent state across
* different JVM executions.
*/
void store(Object key, Object value) throws IOException;
/**
* Holds the given object in a volatile state. This means
* the object store will discard held objects if the
* virtual machine is restarted or some error happens.
*/
void hold(Object key, Object value) throws IOException;
void free();
/**
* Remove the object associated to the given key.
*/
void remove(Object key);
/**
* Indicates if the given key is associated to a contained object.
*/
boolean containsKey(Object key);
/**
* Returns the list of used keys as an Enumeration of Objects.
*/
Enumeration keys();
}
1.1 jakarta-commons-sandbox/simplestore/src/java/org/apache/commons/simplestore/MRUMemoryStore.java
Index: MRUMemoryStore.java
===================================================================
/*****************************************************************************
* Copyright (C) The Apache Software Foundation. All rights reserved. *
* ------------------------------------------------------------------------- *
* This software is published under the terms of the Apache Software License *
* version 1.1, a copy of which has been included with this distribution in *
* the LICENSE file. *
*****************************************************************************/
package org.apache.commons.simplestore;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.LinkedList;
/**
* This class provides a cache algorithm for the requested documents. It
* combines a HashMap and a LinkedList to create a so called MRU (Most Recently
* Used) cache.
*
* @author <a href="mailto:g-froehlich@gmx.de">Gerhard Froehlich</a>
*/
public final class MRUMemoryStore
implements Store {
private int mMaxObjects = 100;
private Hashtable mCache;
private LinkedList mMRUList;
private StoreJanitor mStorejanitor;
public void setMaxObjects(int maxobjects) {
this.mMaxObjects = maxobjects;
}
public int getMaxObjects() {
return this.mMaxObjects;
}
public void initialize() {
this.mCache = new Hashtable((int) (this.getMaxObjects() * 1.2));
this.mMRUList = new LinkedList();
}
/**
* Get the object associated to the given unique key.
*
* @param the Key Object
* @return the Object associated with Key Object
*/
public Object get(Object key) {
Object tmpobject = this.mCache.get(key);
if (tmpobject != null) {
this.mMRUList.remove(key);
this.mMRUList.addFirst(key);
return tmpobject;
}
return null;
}
/**
* Store the given object in a persistent state. It is up to the caller to
* ensure that the key has a persistent state across different JVM
* executions.
*
* @param the Key Object
* @param the Value Object
*/
public void store(Object key, Object value) {
this.hold(key,value);
}
/**
* This method holds the requested object in a HashMap combined with a
* LinkedList to create the MRU. It also stores objects onto the filesystem
* if configured.
*
* @param the Key Object
* @param the Value Object
*/
public void hold(Object key, Object value) {
while (this.mMRUList.size() >= this.mMaxObjects) {
this.free();
}
this.mCache.put(key, value);
this.mMRUList.remove(key);
this.mMRUList.addFirst(key);
}
/**
* Remove the object associated to the given key.
*
* @param the Key object
*/
public void remove(Object key) {
this.mCache.remove(key);
this.mMRUList.remove(key);
}
/**
* Indicates if the given key is associated to a contained object.
*
* @param the Key Object
* @return true if Key exists and false if not
*/
public boolean containsKey(Object key) {
return this.mCache.containsKey(key);
}
/**
* Returns the list of used keys as an Enumeration.
*
* @return the enumeration of the cache
*/
public Enumeration keys() {
return this.mCache.keys();
}
/**
* Frees some of the fast memory used by this store. It removes the last
* element in the store.
*/
public void free() {
try {
if (this.mCache.size() > 0) {
this.mCache.remove(this.mMRUList.getLast());
this.mMRUList.removeLast();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
1.1 jakarta-commons-sandbox/simplestore/src/java/org/apache/commons/simplestore/JispStringKey.java
Index: JispStringKey.java
===================================================================
/*****************************************************************************
* Copyright (C) The Apache Software Foundation. All rights reserved. *
* ------------------------------------------------------------------------- *
* This software is published under the terms of the Apache Software License *
* version 1.1, a copy of which has been included with this distribution in *
* the LICENSE file. *
*****************************************************************************/
package org.apache.commons.simplestore;
import com.coyotegulch.jisp.KeyObject;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
/**
* Wrapper class to make our cache Key compatible with the Jisp KeyObject NOTE:
* This Wrapper is only for String Keys.
*
* @author Gerhard Froehlich <a href="mailto:g-froehlich@gmx.de">
* g-froehlich@gmx.de</a>
*/
final class JispStringKey extends KeyObject {
final static long serialVersionUID = -6894793231339165076L;
private String mKey;
/**
* Constructor for the JispStringKey object
*/
public JispStringKey() {
mKey = new String("");
}
/**
* Constructor for the JispStringKey object
*
* @param the Value of the Key as String
*/
public JispStringKey(String keyValue) {
mKey = keyValue;
}
/**
* Compares two String Keys
*
* @param the KeyObject to be compared
* @return 0 if equal, 1 if greater, -1 if less
*/
public int compareTo(KeyObject key) {
if (key instanceof JispStringKey) {
int comp = mKey.trim().compareTo(((JispStringKey) key).mKey.trim());
if (comp == 0) {
return KEY_EQUAL;
} else {
if (comp < 0) {
return KEY_LESS;
} else {
return KEY_MORE;
}
}
} else {
return KEY_ERROR;
}
}
/**
* Composes a null Kewy
*
* @return a null Key
*/
public KeyObject makeNullKey() {
return new JispStringKey();
}
/**
* The object implements the writeExternal method to save its contents
* by calling the methods of DataOutput for its primitive values or
* calling the writeObject method of ObjectOutput for objects, strings,
* and arrays.
*
* @param out - the stream to write the object to
* @exception IOException
*/
public void writeExternal(ObjectOutput out)
throws IOException {
String outKey;
outKey = new String(mKey);
out.writeUTF(outKey);
}
/**
* The object implements the readExternal method to restore its contents
* by calling the methods of DataInput for primitive types and readObject
* for objects, strings and arrays. The readExternal method must read the
* values in the same sequence and with the same types as were written by writeExternal.
*
* @param in - the stream to read data from in order to restore the object
* @exception IOException
* @exception ClassNotFoundException
*/
public void readExternal(ObjectInput in)
throws IOException, ClassNotFoundException {
mKey = in.readUTF();
}
/**
* Overrides the toString() method
*
* @return the Key as String
*/
public String toString() {
return mKey;
}
}
1.1 jakarta-commons-sandbox/simplestore/src/java/org/apache/commons/simplestore/JispFilesystemStore.java
Index: JispFilesystemStore.java
===================================================================
/**
* Copyright (C) The Apache Software Foundation. All rights reserved. *
* ------------------------------------------------------------------------- *
* This software is published under the terms of the Apache Software License *
* version 1.1, a copy of which has been included with this distribution in *
* the LICENSE file. *
*/
package org.apache.commons.simplestore;
import com.coyotegulch.jisp.BTreeIndex;
import com.coyotegulch.jisp.IndexedObjectDatabase;
import com.coyotegulch.jisp.KeyNotFound;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.Enumeration;
/**
* This store is based on the Jisp library
* (http://www.coyotegulch.com/jisp/index.html). This store uses B-Tree indexes
* to access variable-length serialized data stored in files.
*
* @author Gerhard Froehlich
* <a href="mailto:g-froehlich@gmx.de">Gerhard Froehlich</a>
*/
public final class JispFilesystemStore
implements Store {
/**
* The directory repository
*/
protected File mDirectoryFile;
protected volatile String mDirectoryPath;
/**
* The database
*/
private String mDatabaseName = "default.dat";
private String mIndexName = "default.idx";;
private int mOrder = 101;
private IndexedObjectDatabase mDatabase;
private BTreeIndex mIndex;
public void setDatabaseName(String name) {
this.mDatabaseName = name;
}
public String getDatabaseName() {
return this.mDatabaseName;
}
public void setIndexfileName(String name) {
this.mIndexName = name;
}
public String getIndexfileName() {
return this.mIndexName;
}
public void setOrder(int order) {
this.mOrder = order;
}
public int getOrder() {
return this.mOrder;
}
/**
* Sets the repository's location
*
* @param the new directory value
* @exception IOException
*/
public void setDirectory(final String directory)
throws IOException {
this.setDirectory(new File(directory));
}
/**
* Sets the repository's location
*
* @param the new directory value
* @exception IOException
*/
public void setDirectory(final File directory)
throws IOException {
this.mDirectoryFile = directory;
this.mDirectoryPath = this.mDirectoryFile.getCanonicalPath();
this.mDirectoryPath += File.separator;
if (!this.mDirectoryFile.exists()) {
/* Create it new */
if (!this.mDirectoryFile.mkdir()) {
throw new IOException(
"Error creating store directory '"
+ this.mDirectoryPath + "': ");
}
}
/* Is given file actually a directory? */
if (!this.mDirectoryFile.isDirectory()) {
throw new IOException("'" + this.mDirectoryPath
+ "' is not a directory");
}
/* Is directory readable and writable? */
if (!(this.mDirectoryFile.canRead()
&& this.mDirectoryFile.canWrite())) {
throw new IOException(
"Directory '" + this.mDirectoryPath
+ "' is not readable/writable"
);
}
}
/**
* Returns the repository's full pathname
*
* @return the directory as String
*/
public String getDirectoryPath() {
return this.mDirectoryPath;
}
/**
* Returns a Object from the store associated with the Key Object
*
* @param the Key object
* @return the Object associated with Key Object
*/
public Object get(Object key) {
Object readObj = null;
try {
readObj = mDatabase.read(new JispStringKey(key.toString()), mIndex);
} catch (Exception e) {
e.printStackTrace();
}
return readObj;
}
/**
* Initialize the Component
*/
public void initialize() {
try {
File myFile = new File(this.getDirectoryPath() + mDatabaseName);
if (myFile.exists()) {
mDatabase = new IndexedObjectDatabase(getDirectoryPath()
+ mDatabaseName, false);
mIndex = new BTreeIndex(this.getDirectoryPath() + mIndexName);
mDatabase.attachIndex(mIndex);
} else {
mDatabase = new IndexedObjectDatabase(getDirectoryPath()
+ mDatabaseName, false);
mIndex = new BTreeIndex(this.getDirectoryPath() + mIndexName,
mOrder, new JispStringKey(), false);
mDatabase.attachIndex(mIndex);
}
} catch (KeyNotFound ignore) {
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Store the given Object in the indexed data file.
*
* @param the Key Object
* @param the Value Object
* @exception IOException
*/
public void store(Object key, Object value)
throws IOException {
if (value instanceof Serializable) {
try {
JispStringKey[] keyArray = new JispStringKey[1];
keyArray[0] = new JispStringKey(key.toString());
mDatabase.write(keyArray, (Serializable) value);
} catch (Exception e) {
e.printStackTrace();
}
} else {
throw new IOException("Object not Serializable");
}
}
/**
* Holds the given Object in the indexed data file.
*
* @param the Key Object
* @param the Value Object
* @exception IOException
*/
public void hold(Object key, Object value)
throws IOException {
this.store(key, value);
}
/**
* Frees some values of the data file
*/
public void free() {
//TODO: implementation
}
/**
* Removes a value from the data file with the given key.
*
* @param the Key Object
*/
public void remove(Object key) {
try {
JispStringKey[] keyArray = new JispStringKey[1];
keyArray[0] = new JispStringKey(key.toString());
mDatabase.remove(keyArray);
} catch (KeyNotFound ignore) {
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Test if the the index file contains the given key
*
* @param the Key Object
* @return true if Key exists and false if not
*/
public boolean containsKey(Object key) {
long res = -1;
try {
res = mIndex.findKey(new JispStringKey(key.toString()));
} catch (KeyNotFound ignore) {
} catch (Exception e) {
e.printStackTrace();
}
if (res > 0) {
return true;
} else {
return false;
}
}
/**
* Returns a Enumeration of all Keys in the indexed file
*
* @return Enumeration Object with all existing keys
*/
public Enumeration keys() {
//TODO: Implementation
return null;
}
}
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>