public class ObjectStore {
- private static ObjectStore INSTANCE=new ObjectStore();
- private static HashMap containerMap=new HashMap(); // StoreContainerType/StoreContainer
- private static Logfile storeLog;
- private static long storeHit=0,storeMiss=0;
- private static Class storableObjectInterface=StorableObject.class;
+ private final static ObjectStore INSTANCE=new ObjectStore();
+ private final static HashMap containerMap=new HashMap(); // StoreContainerType/StoreContainer
+ private final static Class storableObjectInterface=StorableObject.class;
+ private static Logfile storeLog;
+ private static long storeHit=0,storeMiss=0;
private ObjectStore() {
}
StorableObject storeObject=null;
StoreContainer stoc = getStoreContainerForSid( sid );
if (stoc!=null) storeObject=stoc.use(sid);
+ else System.out.println("Warning: container not found for: " + sid.toString());
if (storeObject==null) storeMiss++; else storeHit++;
return storeObject;
}
*/
public String toString() {
- StringBuffer sb = new StringBuffer("Mir-ObjectStore v_");
+ float hitRatio=0;
+ long divisor=storeHit+storeMiss;
+ if (divisor>0) hitRatio=(float)storeHit/(float)divisor;
+ hitRatio*=100;
+
+ StringBuffer sb = new StringBuffer("Mir-ObjectStore v_");
sb.append(version()).append("\n");
- sb.append("\nObjectStore hits/misses: ").append(storeHit);
- sb.append("/").append(storeMiss);
- sb.append("\nCurrently ").append(containerMap.size());
+ sb.append("ObjectStore overall hits/misses/ratio: ").append(storeHit);
+ sb.append("/").append(storeMiss).append("/").append(hitRatio);
+ sb.append("%\nCurrently ").append(containerMap.size());
sb.append(" StoreContainer in use - listing information:\n");
// ask container for information
*
* @return String
*/
- private String version() { return "00_daythree";}
+ private String version() { return "00.d4";}
}
\ No newline at end of file
*
* @return Set of StoreIdentifier.
*/
- abstract Set notifyOnReleaseSet();
+ abstract Set getNotifyOnReleaseSet();
}
\ No newline at end of file
private StoreContainerType stocType;
private int maxSize=DEFAULT_SIZE;
private int uniqueId;
+ private int addCount=0,removeCount=0,storeOutCount;
+ private int hitCount=0,missCount=0;
private StoreContainer() {};
}
public StorableObject use(StoreIdentifier sid) {
- // find sid in LinkedList or die
- // move sid to head of linked list
- // return reference on object
- return null;
+ int hit = container.indexOf(sid);
+ if (hit>0) {
+ StoreIdentifier hitSid = (StoreIdentifier)container.get(hit);
+ if ( hitSid!=null ) {
+ hitCount++;
+ return hitSid.use();
+ }
+ }
+ missCount++;
+ return null;
}
public boolean has(StoreIdentifier sid) {
- return true; // yes yes
+ return container.contains(sid);
}
public void add(StoreIdentifier sid) {
if ( sid != null && sid.hasReference() ) {
- //if ( has(sid) )
- // moveToHead(sid);
- //else
+ if ( has(sid) ) {
+ moveToHead(sid);
+ System.err.println("OBJECTStore: tried to add sid " + sid.toString() +
+ " that was already in store.");
+ }
+ else {
container.addFirst(sid);
+ shrinkIfNecessary();
+ addCount++;
+ }
}
- // add to head of linkedlist, if size is exceded throw away tail until
- // size ok.
}
/**
if ( container.contains(sid) ) {
sid.invalidate();
container.remove(sid);
+ removeCount++;
}
}
}
this.maxSize=size;
}
- private void shrink() {
- shrinkToSize(maxSize);
- }
+ private void shrinkIfNecessary() { shrinkToSize(maxSize); }
private void shrinkToSize(int size) {
- if ( size<maxSize && size < container.size() ) {
+ if ( size < container.size() ) {
// shrink
while (size < container.size() ) {
StoreIdentifier sid = (StoreIdentifier)container.getLast();
- sid.release();
container.remove(sid);
+ sid.release();
+ storeOutCount++;
}
}
}
+ private synchronized void moveToHead(StoreIdentifier sid) {
+ if ( sid!=null ) {
+ container.remove(sid);
+ container.addFirst(sid);
+ }
+ }
+
/**
* Method: toString()
* Description: gives out statistical Information, viewable via
* @return String
*/
public String toString() {
+ float hitRatio=0;
+ long divisor=hitCount+missCount;
+ if (divisor>0) hitRatio=(float)hitCount/(float)divisor;
+ hitRatio*=100;
+
StringBuffer sb = new StringBuffer("StoreContainer id: ");
sb.append(uniqueId).append(" for ");
- sb.append(stocType.toString()).append(" // Current/Max size: ");
- sb.append(container.size()).append(" / ");
- sb.append(maxSize).append("\n");
- /** @todo list members ? */
+ sb.append(stocType.toString()).append("\n [current/maximum size: ");
+ sb.append(container.size()).append("/").append(maxSize);
+ sb.append("]\n [added/stored out/removed: ").append(addCount).append("/");
+ sb.append(storeOutCount).append("/").append(removeCount).append("]\n [hit/miss/ratio: ");
+ sb.append(hitCount).append("/").append(missCount).append("/");
+ sb.append(hitRatio).append("%]\n");
+
+ /** @todo list members ? */
return sb.toString();
}
public class StoreContainerType {
- public final static int STOC_TYPE_UNKNOWN=0;
- public final static int STOC_TYPE_ENTITY=1;
- public final static int STOC_TYPE_ENTITYLIST=2;
+ public final static int STOC_TYPE_UNKNOWN=-1;
+ public final static int STOC_TYPE_ENTITY=0;
+ public final static int STOC_TYPE_ENTITYLIST=1;
+ public final static int STOC_TYPE_MAX=STOC_TYPE_ENTITYLIST;
- private static HashMap uniqueTypes = new HashMap(); // StoreKey / StoreContainerType
+ private static HashMap[] uniqueTypes=new HashMap[STOC_TYPE_MAX+1];
private static Logfile storeLog;
private Class stocClass=null;
private int stocType=STOC_TYPE_UNKNOWN;
+ static {
+ uniqueTypes[STOC_TYPE_ENTITY]= new HashMap();
+ uniqueTypes[STOC_TYPE_ENTITYLIST]=new HashMap();
+
+ }
+
private StoreContainerType() {}
private StoreContainerType(Class stocClass, int stocType) {
}
public static StoreContainerType valueOf(Class stoc_class, int stoc_type) {
- /** @todo factory, only gives out types once to make them comparable via ==
- * check if class is StorableObject */
StoreContainerType returnStocType=null;
-
- // inner class for hashlookup
- class StoreKey {
- int storeType; Class storeClass;
- public boolean equals(Object o) {
- if ( o instanceof StoreKey &&
- ((StoreKey)o).storeType==storeType &&
- ((StoreKey)o).storeClass==storeClass )
- return true;
- return false;
- }
- }
-
- StoreKey key = new StoreKey();
- key.storeClass = stoc_class; key.storeType = stoc_type;
- if ( uniqueTypes.containsKey(key) )
- returnStocType=(StoreContainerType)uniqueTypes.get(key);
- else {
- returnStocType=new StoreContainerType(stoc_class,stoc_type);
- uniqueTypes.put(key,returnStocType);
- }
+ if (stoc_type>=0 && stoc_type < STOC_TYPE_MAX) {
+ HashMap current = uniqueTypes[stoc_type];
+ if ( current.containsKey(stoc_class) )
+ returnStocType=(StoreContainerType)current.get(stoc_class);
+ else {
+ returnStocType=new StoreContainerType(stoc_class,stoc_type);
+ current.put(stoc_class,returnStocType);
+ }
+ }
return returnStocType;
}
public String toString() {
- StringBuffer sb = new StringBuffer("StoreContainerType: ");
- sb.append(this.stocClass.toString()).append("@");
- sb.append(stringForStoreType(stocType));
+ StringBuffer sb = new StringBuffer(this.stocClass.toString());
+ sb.append("@").append(stringForStoreType(stocType));
return sb.toString();
}
package mir.storage.store;
/**
- * Title: Class StoreIdentifier
- * Description:
- * Copyright: Copyright (c) 2002
+ * Title: Class StoreIdentifier
+ * Description: StoreIdentifier has two functions.
+ * A) StoreIdenfier holds a reference to a @see StorableObject
+ * or B) StoreIdentifier is used too search for a @see StorableObject
+ * in the @see StoreContainer that matches its
+ *
+ * Copyright: Copyright (c) 2002
* Company: indy
* @author rk
* @version 1.0
private StoreIdentifier() {}
public StoreIdentifier(StorableObject reference, int storeType, String uniqueIdentifier) {
+ this(reference.getClass(), uniqueIdentifier);
this.reference=reference;
- this.uniqueIdentifier=uniqueIdentifier;
- this.stocType = StoreContainerType.valueOf(reference.getClass(), storeType);
}
+ public StoreIdentifier(Class theClass, String uniqueIdentifier) {
+ this(theClass, StoreContainerType.STOC_TYPE_ENTITY,uniqueIdentifier);
+ }
+
+ public StoreIdentifier(Class theClass, int storeType, String uniqueIdentifier) {
+ this.uniqueIdentifier=uniqueIdentifier;
+ this.stocType = StoreContainerType.valueOf(theClass, storeType);
+ }
/**
* Method: ivalidate
* Description:
// avoid deadlock due to propagation.
if (!invalidating) {
invalidating=true;
- Set set = reference.notifyOnReleaseSet();
+ Set set = reference.getNotifyOnReleaseSet();
/** @todo here we should propagate the invalidation all members of Set
* @see StoreContainer. The set may contain objects of different type.*/
release();
this.stocType=null;
}
- public Object use() {
+ public StorableObject use() {
timesUsed++;
return reference;
}
*
*/
public boolean equals(Object sid) {
- if ( sid instanceof StoreIdentifier) {
- if ( ((StoreIdentifier)sid).getStoreContainerType().equals(stocType) &&
- ((StoreIdentifier)sid).getUniqueIdentifier().equals(uniqueIdentifier) )
+ if ( !(sid instanceof StoreIdentifier) ) return false;
+ if ( ((StoreIdentifier)sid).getStoreContainerType()==stocType &&
+ ((StoreIdentifier)sid).getUniqueIdentifier().equals(uniqueIdentifier) )
return true;
- }
return false;
}
public boolean hasReference() { return (reference==null) ? false:true; }
public String toString() {
- return reference.getClass()+"@storetype"+stocType.toString()+"."
- +uniqueIdentifier+" ("+timesUsed+") times used )";
+ StringBuffer id = new StringBuffer(uniqueIdentifier);
+ id.append("@storetype: ").append(stocType.toString());
+ if (reference != null) id.append(" ("+timesUsed).append(") times used.");
+ return id.toString();
}
return new StoreIdentifier(this, StoreContainerType.STOC_TYPE_ENTITY,id);
}
- public Set notifyOnReleaseSet() {
+ public Set getNotifyOnReleaseSet() {
return null;
}
}
\ No newline at end of file
--- /dev/null
+package mir.storage.store.test;
+
+/**
+ * Title:
+ * Description:
+ * Copyright: Copyright (c) 2002
+ * Company:
+ * @author
+ * @version 1.0
+ */
+
+import java.util.*;
+import mir.storage.store.*;
+
+public class EntityC2 implements StorableObject {
+
+ String id;
+
+ public EntityC2(String id) {
+ this.id=id;
+ }
+
+ public StoreIdentifier getStoreIdentifier() {
+ return new StoreIdentifier(this, StoreContainerType.STOC_TYPE_ENTITY,id);
+ }
+
+ public Set getNotifyOnReleaseSet() {
+ return null;
+ }
+}
\ No newline at end of file
--- /dev/null
+package mir.storage.store.test;
+
+/**
+ * Title:
+ * Description:
+ * Copyright: Copyright (c) 2002
+ * Company:
+ * @author
+ * @version 1.0
+ */
+
+import java.util.*;
+import mir.storage.store.*;
+
+public class EntityC3 implements StorableObject {
+
+ String id;
+
+ public EntityC3(String id) {
+ this.id=id;
+ }
+
+ public StoreIdentifier getStoreIdentifier() {
+ return new StoreIdentifier(this, StoreContainerType.STOC_TYPE_ENTITY,id);
+ }
+
+ public Set getNotifyOnReleaseSet() {
+ return null;
+ }
+}
\ No newline at end of file
}
public void startTest() {
- //System.out.println(o_store.toString());
+
EntityC1 c1 = new EntityC1("1");
o_store.add(c1.getStoreIdentifier());
- EntityC1 c2 = new EntityC1("2");
- o_store.add(c2.getStoreIdentifier());
+ EntityC1 c12 = new EntityC1("2");
+ o_store.add(c12.getStoreIdentifier());
+ o_store.add(c12.getStoreIdentifier()); // should not be added as it's there already
+
+ EntityC2 c2;
+ for (int i=0; i<20; i++) {
+ c2 = new EntityC2(""+i);
+ o_store.add(c2.getStoreIdentifier());
+ } // should contain only 10
+
+ // test cycle: search in store
+
+ StorableObject reference; StoreIdentifier search_sid;
+
+ // search for EntityC1
+ search_sid=new StoreIdentifier(EntityC1.class,"1");
+ reference=o_store.use(search_sid);
+ if (reference==null)
+ System.out.println("--- should have found" + search_sid.toString());
+
+ search_sid=new StoreIdentifier(EntityC1.class,"A");
+ reference=o_store.use(search_sid);
+ if (reference!=null)
+ System.out.println("--- should not have found" + search_sid.toString());
+
+ search_sid=new StoreIdentifier(EntityC3.class,"1");
+ reference=o_store.use(search_sid);
+ if (reference!=null)
+ System.out.println("--- should not have found" + search_sid.toString());
+
System.out.println(o_store.toString());
/** @todo compare values of store and state failed if values are not