Return-Path:
Property Key | *Property Values | *
timeout | *@@ -73,7 +72,7 @@ * * | *
autoSync | *@@ -95,7 +94,7 @@ * * | *
cachingKeyType | *@@ -162,12 +161,12 @@ useAutoSync = prop == null ? false : (Boolean.valueOf((prop.getProperty(AUTOSYNC_PROP, "false")).trim())).booleanValue(); - if (useAutoSync && broker != null) + if(useAutoSync && broker != null) { // we add this instance as a permanent PBStateListener broker.addListener(this, true); } - if (useAutoSync && broker == null) + if(useAutoSync && broker == null) { LoggerFactory.getDefaultLogger().info("[" + ObjectCacheDefaultImpl.class.getName() + "] Can't enable " + AUTOSYNC_PROP + ", because given PB instance is null"); @@ -193,7 +192,7 @@ public void cache(Identity oid, Object obj) { processQueue(); - if ((obj != null)) + if((obj != null)) { traceIdentity(oid); objectTable.put(buildKey(oid), new CacheEntry(obj, oid, queue)); @@ -211,10 +210,10 @@ Object result = null; CacheEntry entry = (CacheEntry) objectTable.get(buildKey(oid)); - if (entry != null && entry.oid.getObjectsTopLevelClass().equals(oid.getObjectsTopLevelClass())) + if(entry != null) { result = entry.get(); - if (result == null || entry.lifetime < System.currentTimeMillis()) + if(result == null || entry.lifetime < System.currentTimeMillis()) { /* cached object was removed by gc or lifetime was exhausted @@ -247,7 +246,7 @@ public void remove(Identity oid) { processQueue(); - if (oid != null) + if(oid != null) { removeTracedIdentity(oid); objectTable.remove(buildKey(oid)); @@ -271,7 +270,7 @@ private void traceIdentity(Identity oid) { - if (useAutoSync && (broker != null) && broker.isInTransaction()) + if(useAutoSync && (broker != null) && broker.isInTransaction()) { identitiesInWork.add(oid); } @@ -287,34 +286,41 @@ Identity oid; LoggerFactory.getDefaultLogger().info("[" + this.getClass().getName() + "] tx was aborted," + " remove " + identitiesInWork.size() + " traced (potentially modified) objects from cache"); - for (Iterator iterator = identitiesInWork.iterator(); iterator.hasNext();) + for(Iterator iterator = identitiesInWork.iterator(); iterator.hasNext();) { oid = (Identity) iterator.next(); objectTable.remove(buildKey(oid)); } } - private Integer buildKey(Identity oid) + private Object buildKey(Identity oid) { - int key = 0; + Object key; switch(cachingKeyType) { case 0: - key = oid.hashCode(); + key = oid; break; case 1: - key = new HashCodeBuilder().append(broker.getPBKey().getAlias().hashCode()).append(oid.hashCode()).toHashCode(); + key = new OrderedTuple(oid, broker.getPBKey().getAlias()); break; case 2: - key = new HashCodeBuilder().append(broker.getDescriptorRepository().hashCode()).append(oid.hashCode()).toHashCode(); + /* + this ObjectCache implementation only works in single JVM, so the hashCode + of the DescriptorRepository class is unique + TODO: problem when different versions of same DR are used + */ + key = new OrderedTuple(oid, + new Integer(broker.getDescriptorRepository().hashCode())); break; case 3: - key = new HashCodeBuilder().append(broker.getDescriptorRepository().hashCode()).append(broker.getPBKey().getAlias().hashCode()).append(oid.hashCode()).toHashCode(); + key = new OrderedTuple(oid, broker.getPBKey().getAlias(), + new Integer(broker.getDescriptorRepository().hashCode())); break; default: - throw new OJBRuntimeException("Unexpected error, 'cacheType ="+cachingKeyType+"' was not supported"); + throw new OJBRuntimeException("Unexpected error, 'cacheType =" + cachingKeyType + "' was not supported"); } - return new Integer(key); + return key; } public void beforeRollback(PBStateEvent event) @@ -355,7 +361,7 @@ private void processQueue() { CacheEntry sv; - while ((sv = (CacheEntry) queue.poll()) != null) + while((sv = (CacheEntry) queue.poll()) != null) { removeTracedIdentity(sv.oid); objectTable.remove(buildKey(sv.oid)); // we can access private data! @@ -375,7 +381,7 @@ super(object, q); oid = k; // if timeout is negative, lifetime of object never expire - if (timeout < 0) + if(timeout < 0) { lifetime = Long.MAX_VALUE; } @@ -383,6 +389,112 @@ { lifetime = System.currentTimeMillis() + timeout; } + } + } + + /** + * Implements equals() and hashCode() for an ordered tuple of constant(!) + * objects + * + * @author Gerhard Grosse + * @since Oct 12, 2004 + */ + static final class OrderedTuple + { + private static int[] multipliers = + new int[]{13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 51}; + + private Object[] elements; + private int hashCode; + + public OrderedTuple(Object element) + { + elements = new Object[1]; + elements[0] = element; + hashCode = calcHashCode(); + } + + public OrderedTuple(Object element1, Object element2) + { + elements = new Object[2]; + elements[0] = element1; + elements[1] = element2; + hashCode = calcHashCode(); + } + + public OrderedTuple(Object element1, Object element2, Object element3) + { + elements = new Object[3]; + elements[0] = element1; + elements[1] = element2; + elements[2] = element3; + hashCode = calcHashCode(); + } + + public OrderedTuple(Object[] elements) + { + this.elements = elements; + this.hashCode = calcHashCode(); + } + + private int calcHashCode() + { + int code = 7; + for(int i = 0; i < elements.length; i++) + { + int m = i % multipliers.length; + code += elements[i].hashCode() * multipliers[m]; + } + return code; + } + + public boolean equals(Object obj) + { + if(!(obj instanceof OrderedTuple)) + { + return false; + } + else + { + OrderedTuple other = (OrderedTuple) obj; + if(this.hashCode != other.hashCode) + { + return false; + } + else if(this.elements.length != other.elements.length) + { + return false; + } + else + { + for(int i = 0; i < elements.length; i++) + { + if(!this.elements[i].equals(other.elements[i])) + { + return false; + } + } + return true; + } + } + } + + public int hashCode() + { + return hashCode; + } + + public String toString() + { + StringBuffer s = new StringBuffer(); + s.append('{'); + for(int i = 0; i < elements.length; i++) + { + s.append(elements[i]).append('#').append(elements[i].hashCode()).append(','); + } + s.setCharAt(s.length() - 1, '}'); + s.append("#").append(hashCode); + return s.toString(); } } --------------------------------------------------------------------- To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org For additional commands, e-mail: ojb-dev-help@db.apache.org |