Return-Path: Delivered-To: apmail-db-ojb-dev-archive@www.apache.org Received: (qmail 5536 invoked from network); 18 Nov 2004 23:56:29 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur-2.apache.org with SMTP; 18 Nov 2004 23:56:29 -0000 Received: (qmail 28998 invoked by uid 500); 18 Nov 2004 23:56:29 -0000 Delivered-To: apmail-db-ojb-dev-archive@db.apache.org Received: (qmail 28956 invoked by uid 500); 18 Nov 2004 23:56:28 -0000 Mailing-List: contact ojb-dev-help@db.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Help: List-Post: List-Id: "OJB Developers List" Reply-To: "OJB Developers List" Delivered-To: mailing list ojb-dev@db.apache.org Received: (qmail 28942 invoked by uid 500); 18 Nov 2004 23:56:28 -0000 Received: (qmail 28938 invoked by uid 99); 18 Nov 2004 23:56:28 -0000 X-ASF-Spam-Status: No, hits=-10.0 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.28) with SMTP; Thu, 18 Nov 2004 15:56:24 -0800 Received: (qmail 5494 invoked by uid 1510); 18 Nov 2004 23:56:23 -0000 Date: 18 Nov 2004 23:56:23 -0000 Message-ID: <20041118235623.5493.qmail@minotaur.apache.org> From: arminw@apache.org To: db-ojb-cvs@apache.org Subject: cvs commit: db-ojb/src/java/org/apache/ojb/broker/cache ObjectCacheDefaultImpl.java X-Virus-Checked: Checked X-Spam-Rating: minotaur-2.apache.org 1.6.2 0/1000/N arminw 2004/11/18 15:56:23 Modified: src/java/org/apache/ojb/broker/cache Tag: OJB_1_0_RELEASE ObjectCacheDefaultImpl.java Log: bug fix, made stupid refactoring (1.0->1.0.1) by replacing Identity key with simple hash code based key http://nagoya.apache.org/eyebrowse/ReadMsg?listName=ojb-user@db.apache.org&msgNo=15063 Revision Changes Path No revision No revision 1.24.2.2 +137 -25 db-ojb/src/java/org/apache/ojb/broker/cache/ObjectCacheDefaultImpl.java Index: ObjectCacheDefaultImpl.java =================================================================== RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/cache/ObjectCacheDefaultImpl.java,v retrieving revision 1.24.2.1 retrieving revision 1.24.2.2 diff -u -r1.24.2.1 -r1.24.2.2 --- ObjectCacheDefaultImpl.java 4 Aug 2004 00:31:51 -0000 1.24.2.1 +++ ObjectCacheDefaultImpl.java 18 Nov 2004 23:56:23 -0000 1.24.2.2 @@ -26,12 +26,11 @@ import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle; -import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.ojb.broker.Identity; +import org.apache.ojb.broker.OJBRuntimeException; import org.apache.ojb.broker.PBStateEvent; import org.apache.ojb.broker.PBStateListener; import org.apache.ojb.broker.PersistenceBroker; -import org.apache.ojb.broker.OJBRuntimeException; import org.apache.ojb.broker.util.logging.LoggerFactory; /** @@ -52,13 +51,13 @@ * Implementation configuration properties: *

*

- * + *

* * * * * - * + *

*

* * * - * + *

*

* * * - * + *

*

* *
Property KeyProperty 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