[jbosscache-issues] [JBoss JIRA] (JBCACHE-394) Performance Improvements in CachedSetImpl

Scott Marlow (JIRA) jira-events at lists.jboss.org
Mon Aug 6 16:28:08 EDT 2012


     [ https://issues.jboss.org/browse/JBCACHE-394?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Scott Marlow reassigned JBCACHE-394:
------------------------------------

    Assignee: Scott Marlow  (was: Scott Marlow (Novell))

    
> Performance Improvements in CachedSetImpl
> -----------------------------------------
>
>                 Key: JBCACHE-394
>                 URL: https://issues.jboss.org/browse/JBCACHE-394
>             Project: JBoss Cache
>          Issue Type: Patch
>      Security Level: Public(Everyone can see) 
>          Components: Legacy POJO Cache 
>            Reporter: Brian Stansberry
>            Assignee: Scott Marlow
>             Fix For: 1.3.0.GA
>
>         Attachments: CachedSetImpl.diff, CachedSetImpl.java
>
>
> Jussi Pyörre posted a revised version of CachedSetImpl on the user forum. I haven't evaluated it, but am moving it to JIRA so we don't lose track of it.
> From the forum post:
> As I was running into severe performance problems with CachedSetImpl in TreeCacheAop, I wrote a new version with increased performance (can't remember the exact amount of improvement, but it was substantial anyway). This version has two main improvements:
> 1. The older version used size() method several times in next() method of the IteratorImpl. Since size() is a quite heavy operation in CachedSetImpl, the performance was poor. New version doesn't use size() for iterations at all.
> 2. The old version used ArrayList style indexing for node children names. This was only slowing things down. The new version uses the first available integer as a new child's name. For example, if first there were three children (0, 1 and 2) and '1' was destroyed, '0' and '2' would not get renamed. The next element addition would use '1' as its child name.
> As I am currently really busy, I unfortunately don't have time to get familiar with your ways of contributing to source code, so I'll just publish the new version here. So, here's the new CachedSetImpl:
> Code:
> /*
>  * JBoss, the OpenSource J2EE webOS
>  *
>  * Distributable under LGPL license.
>  * See terms of license at gnu.org.
>  */
> package org.jboss.cache.aop.collection;
> import org.jboss.cache.CacheException;
> import org.jboss.cache.Fqn;
> import org.jboss.cache.DataNode;
> import org.jboss.cache.aop.TreeCacheAop;
> import org.jboss.cache.aop.util.AopUtil;
> import org.jboss.util.NestedRuntimeException;
> import java.util.AbstractSet;
> import java.util.Collection;
> import java.util.Collections;
> import java.util.Iterator;
> import java.util.Map;
> import java.util.NoSuchElementException;
> import java.util.Set;
> /**
>  * Set that uses cache as a underlying backend store
>  * 
>  * @author Ben Wang, Jussi Pyörre
>  */
> public class CachedSetImpl extends AbstractSet {
> 	protected TreeCacheAop cache;
> 	protected AbstractCollectionInterceptor interceptor;
> 	public CachedSetImpl(TreeCacheAop cache,
> 			AbstractCollectionInterceptor interceptor) {
> 		this.cache = cache;
> 		this.interceptor = interceptor;
> 	}
> 	private Collection keySet() {
> 		DataNode node = getNode();
> 		if (node != null) {
> 			Map children = node.getChildren();
> 			if (children != null) {
> 				return children.keySet();
> 			}
> 		}
> 		return Collections.EMPTY_SET;
> 	}
> 	private class IteratorImpl implements Iterator {
> 		private Iterator iterator;
> 		private Object key;
> 		private IteratorImpl(Collection keys) {
> 			iterator = keys.iterator();
> 		}
> 		private IteratorImpl() {
> 			iterator = CachedSetImpl.this.keySet().iterator();
> 		}
> 		public boolean hasNext() {
> 			return iterator.hasNext();
> 		}
> 		public Object next() throws NoSuchElementException {
> 			if (!this.hasNext()) {
> 				throw new NoSuchElementException();
> 			}
> 			this.key = iterator.next();
> 			try {
> 				return cache
> 						.getObject(AopUtil.constructFqn(getFqn(), this.key));
> 			} catch (CacheException e) {
> 				throw new RuntimeException(e);
> 			}
> 		}
> 		public void remove() throws IllegalStateException {
> 			if (this.key == null) {
> 				throw new IllegalStateException();
> 			}
> 			try {
> 				cache.removeObject(AopUtil.constructFqn(getFqn(), this.key));
> 			} catch (CacheException e) {
> 				throw new RuntimeException(e);
> 			}
> 		}
> 	}
> 	// protected static final Log log_=LogFactory.getLog(CachedSetImpl.class);
> 	protected DataNode getNode() {
> 		try {
> 			return cache.get(getFqn());
> 		} catch (Exception e) {
> 			throw new NestedRuntimeException(e);
> 		}
> 	}
> 	protected Fqn getFqn() {
> 		// Need this since fqn can be reset.
> 		return interceptor.getFqn();
> 	}
> 	public boolean add(Object o) {
> 		Collection keys = keySet();
> 		// This could be done with 'contains(o)' but it would invoke 'keySet()'
> 		// twice
> 		for (Iterator iter = new IteratorImpl(keys); iter.hasNext();)
> 			if (iter.next() == o)
> 				return false;
> 		// Search first available key. This is a fast operation as the key set
> 		// is already available
> 		int key = 0;
> 		while (keys.contains(Integer.toString(key)))
> 			key++;
> 		try {
> 			cache.putObject(AopUtil.constructFqn(getFqn(), Integer
> 					.toString(key)), o);
> 		} catch (CacheException e) {
> 			throw new RuntimeException(e);
> 		}
> 		return true;
> 	}
> 	public Iterator iterator() {
> 		return new IteratorImpl();
> 	}
> 	public int size() {
> 		return keySet().size();
> 	}
> 	public boolean equals(Object o) {
> 		if (o == null)
> 			return false;
> 		if (o == this)
> 			return true;
> 		try {
> 			Set set = (Set) o;
> 			return (set.size() == keySet().size() && this.containsAll(set));
> 		} catch (ClassCastException e) {
> 			return false;
> 		}
> 	}
> }
> 	
> It might need modification with older JDKs with rethrowing of catched exceptions (I use RuntimeException as you seem to throw NestedRuntimeException...). Anyway, that is a minor modification, if needed. 

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.jboss.org/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

       



More information about the jbosscache-issues mailing list