james-server-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From e...@apache.org
Subject svn commit: r1476501 - in /james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching: ./ guava/
Date Sat, 27 Apr 2013 06:33:51 GMT
Author: eric
Date: Sat Apr 27 06:33:50 2013
New Revision: 1476501

URL: http://svn.apache.org/r1476501
Log:
Readd first implementation of mailox-caching (IMAP-373)

Added:
    james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/CacheInvalidatingMailboxListener.java
    james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/CacheLoaderFromUnderlying.java
    james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/CachingMailboxMapper.java
    james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/CachingMailboxSessionMapperFactory.java
    james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/CachingMessageMapper.java
    james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/MailboxByPathCache.java
    james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/MailboxMetadataCache.java
    james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/guava/AbstractGuavaCache.java
    james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/guava/GuavaCacheWrapper.java
    james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/guava/GuavaMailboxByPathCache.java
    james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/guava/GuavaMailboxMetadataCache.java

Added: james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/CacheInvalidatingMailboxListener.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/CacheInvalidatingMailboxListener.java?rev=1476501&view=auto
==============================================================================
--- james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/CacheInvalidatingMailboxListener.java
(added)
+++ james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/CacheInvalidatingMailboxListener.java
Sat Apr 27 06:33:50 2013
@@ -0,0 +1,47 @@
+package org.apache.mailbox.caching;
+
+import org.apache.james.mailbox.MailboxListener;
+import org.apache.james.mailbox.MailboxListenerSupport;
+import org.apache.james.mailbox.exception.MailboxException;
+
+public class CacheInvalidatingMailboxListener<Id> implements MailboxListener {
+
+	private MailboxByPathCache<Id> mailboxCacheByPath;
+	private MailboxMetadataCache<Id> mailboxMetadataCache;
+
+	public CacheInvalidatingMailboxListener(MailboxByPathCache<Id> mailboxCacheByPath,
MailboxMetadataCache<Id> mailboxMetadataCache) {
+		this.mailboxCacheByPath = mailboxCacheByPath;
+		this.mailboxMetadataCache = mailboxMetadataCache;
+	}
+	
+	public void register(MailboxListenerSupport listener) throws MailboxException {
+		listener.addGlobalListener(this, null);
+	}
+	
+	@Override
+	public void event(Event event) {
+		// TODO this needs for sure to be smarter
+		try {
+			if (event instanceof MessageEvent) {
+				// invalidate the metadata caches
+					invalidateMetadata(event);
+			}
+			invalidateMailbox(event);
+		} catch (MailboxException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+	}
+
+	private void invalidateMetadata(Event event) throws MailboxException {
+		//HMM, race conditions welcome?
+		mailboxMetadataCache.invalidate(mailboxCacheByPath.findMailboxByPath(event.getMailboxPath(),
null));
+		
+	}
+
+	private void invalidateMailbox(Event event) {
+		mailboxCacheByPath.invalidate(event.getMailboxPath());		
+	}
+
+}

Added: james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/CacheLoaderFromUnderlying.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/CacheLoaderFromUnderlying.java?rev=1476501&view=auto
==============================================================================
--- james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/CacheLoaderFromUnderlying.java
(added)
+++ james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/CacheLoaderFromUnderlying.java
Sat Apr 27 06:33:50 2013
@@ -0,0 +1,5 @@
+package org.apache.mailbox.caching;
+
+public interface CacheLoaderFromUnderlying<Key, Value, Underlying, Except extends Throwable>
{
+	Value load(Key key, Underlying underlying) throws Except;
+}

Added: james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/CachingMailboxMapper.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/CachingMailboxMapper.java?rev=1476501&view=auto
==============================================================================
--- james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/CachingMailboxMapper.java
(added)
+++ james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/CachingMailboxMapper.java
Sat Apr 27 06:33:50 2013
@@ -0,0 +1,79 @@
+package org.apache.mailbox.caching;
+import java.util.List;
+
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.exception.MailboxNotFoundException;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.store.mail.MailboxMapper;
+import org.apache.james.mailbox.store.mail.model.Mailbox;
+
+
+public class CachingMailboxMapper<Id> implements MailboxMapper<Id> {
+
+	private MailboxMapper<Id> underlying;
+	private MailboxByPathCache<Id> cache;
+
+	public CachingMailboxMapper(MailboxMapper<Id> underlying, MailboxByPathCache<Id>
cache) {
+		this.underlying = underlying;
+		this.cache = cache;
+	}
+	
+	@Override
+	public void endRequest() {
+		underlying.endRequest();		
+	}
+
+	@Override
+	public <T> T execute(Transaction<T> transaction) throws MailboxException {
+		return underlying.execute(transaction);
+	}
+
+	@Override
+	public void save(Mailbox<Id> mailbox) throws MailboxException {
+		invalidate(mailbox);
+		underlying.save(mailbox);
+	}
+
+	@Override
+	public void delete(Mailbox<Id> mailbox) throws MailboxException {
+		cache.invalidate(mailbox);
+		underlying.delete(mailbox);
+	}
+
+	@Override
+	public Mailbox<Id> findMailboxByPath(MailboxPath mailboxName)
+			throws MailboxException, MailboxNotFoundException {
+		try {
+			return cache.findMailboxByPath(mailboxName, underlying);
+		} catch (MailboxNotFoundException e) {
+			cache.invalidate(mailboxName);
+			throw e;
+		}
+	}
+
+	@Override
+	public List<Mailbox<Id>> findMailboxWithPathLike(MailboxPath mailboxPath)
+			throws MailboxException {
+		// TODO possible to meaningfully cache it?
+		return underlying.findMailboxWithPathLike(mailboxPath);
+	}
+
+	@Override
+	public boolean hasChildren(Mailbox<Id> mailbox, char delimiter)
+			throws MailboxException, MailboxNotFoundException {
+		// TODO possible to meaningfully cache it?
+		return hasChildren(mailbox, delimiter);
+	}
+
+	@Override
+	public List<Mailbox<Id>> list() throws MailboxException {
+		// TODO possible to meaningfully cache it? is it used at all?
+		return underlying.list();
+	}
+
+	private void invalidate(Mailbox<Id> mailbox) {
+		cache.invalidate(mailbox);
+	}
+
+
+}

Added: james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/CachingMailboxSessionMapperFactory.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/CachingMailboxSessionMapperFactory.java?rev=1476501&view=auto
==============================================================================
--- james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/CachingMailboxSessionMapperFactory.java
(added)
+++ james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/CachingMailboxSessionMapperFactory.java
Sat Apr 27 06:33:50 2013
@@ -0,0 +1,43 @@
+package org.apache.mailbox.caching;
+
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.exception.SubscriptionException;
+import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
+import org.apache.james.mailbox.store.mail.MailboxMapper;
+import org.apache.james.mailbox.store.mail.MessageMapper;
+import org.apache.james.mailbox.store.user.SubscriptionMapper;
+
+public class CachingMailboxSessionMapperFactory<Id> extends
+		MailboxSessionMapperFactory<Id> {
+
+	private MailboxSessionMapperFactory<Id> underlying;
+	private MailboxByPathCache<Id> mailboxByPathCache;
+	private MailboxMetadataCache<Id> mailboxMetadataCache;
+
+	public CachingMailboxSessionMapperFactory(MailboxSessionMapperFactory<Id> underlying,
MailboxByPathCache<Id> mailboxByPathCache, MailboxMetadataCache<Id> mailboxMetadataCache)
{
+		this.underlying = underlying;
+		this.mailboxByPathCache = mailboxByPathCache;
+		this.mailboxMetadataCache = mailboxMetadataCache;
+	}
+	
+	@Override
+	public MessageMapper<Id> createMessageMapper(MailboxSession session)
+			throws MailboxException {
+		return new CachingMessageMapper<Id>(underlying.createMessageMapper(session), mailboxByPathCache);
+	}
+
+	@Override
+	public MailboxMapper<Id> createMailboxMapper(MailboxSession session)
+			throws MailboxException {
+	    //TODO(eric) this cast will not work!!! Temporary adding it to compile the project...
+		return (MailboxMapper<Id>) new CachingMessageMapper<Id>(underlying.createMailboxMapper(session),
mailboxMetadataCache);
+	}
+
+	@Override
+	public SubscriptionMapper createSubscriptionMapper(MailboxSession session)
+			throws SubscriptionException {
+		return underlying.createSubscriptionMapper(session);
+	}
+
+}

Added: james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/CachingMessageMapper.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/CachingMessageMapper.java?rev=1476501&view=auto
==============================================================================
--- james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/CachingMessageMapper.java
(added)
+++ james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/CachingMessageMapper.java
Sat Apr 27 06:33:50 2013
@@ -0,0 +1,138 @@
+package org.apache.mailbox.caching;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.mail.Flags;
+
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.model.MessageMetaData;
+import org.apache.james.mailbox.model.MessageRange;
+import org.apache.james.mailbox.model.UpdatedFlags;
+import org.apache.james.mailbox.store.mail.MailboxMapper;
+import org.apache.james.mailbox.store.mail.MessageMapper;
+import org.apache.james.mailbox.store.mail.model.Mailbox;
+import org.apache.james.mailbox.store.mail.model.Message;
+
+public class CachingMessageMapper<Id> implements MessageMapper<Id> {
+	
+	private MessageMapper<Id> underlying;
+	private MailboxMetadataCache<Id> cache;
+
+	public CachingMessageMapper(MessageMapper<Id> underlying, MailboxMetadataCache<Id>
cache) {
+		this.underlying = underlying;
+		this.cache = cache;
+	}
+	
+    public CachingMessageMapper(MessageMapper<Id> createMessageMapper, MailboxByPathCache<Id>
mailboxByPathCache) {
+        // TODO(eric) Auto-generated constructor stub
+    }
+
+    public CachingMessageMapper(MailboxMapper<Id> mailboxMapper, MailboxMetadataCache<Id>
mailboxMetadataCache) {
+        // TODO(eric) Auto-generated constructor stub
+    }
+
+    @Override
+	public void endRequest() {
+		underlying.endRequest();
+	}
+
+	@Override
+	public <T> T execute(Transaction<T> transaction) throws MailboxException {
+		return underlying.execute(transaction);
+	}
+
+	@Override
+	public Iterator<Message<Id>> findInMailbox(Mailbox<Id> mailbox,
+			MessageRange set,
+			org.apache.james.mailbox.store.mail.MessageMapper.FetchType type,
+			int limit) throws MailboxException {
+		return underlying.findInMailbox(mailbox, set, type, limit);
+	}
+
+	@Override
+	public Map<Long, MessageMetaData> expungeMarkedForDeletionInMailbox(
+			Mailbox<Id> mailbox, MessageRange set) throws MailboxException {
+		invalidateMetadata(mailbox);
+		return underlying.expungeMarkedForDeletionInMailbox(mailbox, set);
+	}
+
+	@Override
+	public long countMessagesInMailbox(Mailbox<Id> mailbox)
+			throws MailboxException {
+		return cache.countMessagesInMailbox(mailbox, underlying);
+	}
+
+	@Override
+	public long countUnseenMessagesInMailbox(Mailbox<Id> mailbox)
+			throws MailboxException {
+		return cache.countUnseenMessagesInMailbox(mailbox, underlying);
+	}
+
+	@Override
+	public void delete(Mailbox<Id> mailbox, Message<Id> message)
+			throws MailboxException {
+		invalidateMetadata(mailbox);
+		underlying.delete(mailbox, message);
+		
+	}
+
+	@Override
+	public Long findFirstUnseenMessageUid(Mailbox<Id> mailbox)
+			throws MailboxException {
+		return cache.findFirstUnseenMessageUid(mailbox, underlying);
+	}
+
+	@Override
+	public List<Long> findRecentMessageUidsInMailbox(Mailbox<Id> mailbox)
+			throws MailboxException {
+		// TODO can be meaningfully cached?
+		return underlying.findRecentMessageUidsInMailbox(mailbox);
+	}
+
+	@Override
+	public MessageMetaData add(Mailbox<Id> mailbox, Message<Id> message)
+			throws MailboxException {
+		invalidateMetadata(mailbox);
+		return underlying.add(mailbox, message);
+	}
+
+	@Override
+	public Iterator<UpdatedFlags> updateFlags(Mailbox<Id> mailbox, Flags flags,
+			boolean value, boolean replace, MessageRange set)
+			throws MailboxException {
+		//check if there are in fact any updates
+		if (set.iterator().hasNext())
+			invalidateMetadata(mailbox);
+		return underlying.updateFlags(mailbox, flags, value, replace, set);
+	}
+
+
+	@Override
+	public MessageMetaData copy(Mailbox<Id> mailbox, Message<Id> original)
+			throws MailboxException {
+		invalidateMetadata(mailbox);
+		return underlying.copy(mailbox, original);
+	}
+
+	@Override
+	public long getLastUid(Mailbox<Id> mailbox) throws MailboxException {
+		return cache.getLastUid(mailbox, underlying);
+	}
+
+	@Override
+	public long getHighestModSeq(Mailbox<Id> mailbox) throws MailboxException {
+		return cache.getHighestModSeq(mailbox, underlying);
+	}
+
+	private void invalidateMetadata(Mailbox<Id> mailbox) {
+		cache.invalidate(mailbox);
+		
+	}
+
+    @Override
+    public MessageMetaData move(Mailbox<Id> mailbox, Message<Id> original) throws
MailboxException {
+        throw new UnsupportedOperationException("Move is not yet supported");
+    }
+
+}

Added: james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/MailboxByPathCache.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/MailboxByPathCache.java?rev=1476501&view=auto
==============================================================================
--- james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/MailboxByPathCache.java
(added)
+++ james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/MailboxByPathCache.java
Sat Apr 27 06:33:50 2013
@@ -0,0 +1,22 @@
+package org.apache.mailbox.caching;
+
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.exception.MailboxNotFoundException;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.store.mail.MailboxMapper;
+import org.apache.james.mailbox.store.mail.model.Mailbox;
+
+public interface MailboxByPathCache<Id> {
+
+	public abstract Mailbox<Id> findMailboxByPath(MailboxPath mailboxName,
+			MailboxMapper<Id> underlying) throws MailboxNotFoundException,
+			MailboxException;
+
+	public abstract void invalidate(Mailbox<Id> mailbox);
+	
+	public abstract void invalidate(MailboxPath mailboxPath);
+
+	// for the purpose of cascading the invalidations; does it make sense? 
+	//public void connectTo(MailboxMetadataCache<Id> mailboxMetadataCache);
+
+}

Added: james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/MailboxMetadataCache.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/MailboxMetadataCache.java?rev=1476501&view=auto
==============================================================================
--- james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/MailboxMetadataCache.java
(added)
+++ james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/MailboxMetadataCache.java
Sat Apr 27 06:33:50 2013
@@ -0,0 +1,28 @@
+package org.apache.mailbox.caching;
+
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.store.mail.MessageMapper;
+import org.apache.james.mailbox.store.mail.model.Mailbox;
+
+public interface MailboxMetadataCache<Id> {
+
+	public abstract long countMessagesInMailbox(Mailbox<Id> mailbox,
+			MessageMapper<Id> underlying) throws MailboxException;
+
+	public abstract long countUnseenMessagesInMailbox(Mailbox<Id> mailbox,
+			MessageMapper<Id> underlying) throws MailboxException;
+
+	public abstract Long findFirstUnseenMessageUid(Mailbox<Id> mailbox,
+			MessageMapper<Id> underlying) throws MailboxException;
+
+	public abstract long getLastUid(Mailbox<Id> mailbox,
+			MessageMapper<Id> underlying) throws MailboxException;
+
+	public abstract long getHighestModSeq(Mailbox<Id> mailbox,
+			MessageMapper<Id> underlying) throws MailboxException;
+
+	public abstract void invalidate(Mailbox<Id> mailbox);
+
+//	public abstract void invalidate(MailboxPath mailboxPath);
+
+}
\ No newline at end of file

Added: james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/guava/AbstractGuavaCache.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/guava/AbstractGuavaCache.java?rev=1476501&view=auto
==============================================================================
--- james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/guava/AbstractGuavaCache.java
(added)
+++ james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/guava/AbstractGuavaCache.java
Sat Apr 27 06:33:50 2013
@@ -0,0 +1,15 @@
+package org.apache.mailbox.caching.guava;
+
+import java.util.concurrent.TimeUnit;
+
+import com.google.common.cache.CacheBuilder;
+
+public class AbstractGuavaCache {
+
+	// TODO this can probably be instantiated more elegant way
+	protected static final CacheBuilder<Object, Object> BUILDER = 
+			CacheBuilder.newBuilder()			
+			.maximumSize(100000)
+			.expireAfterWrite(15, TimeUnit.MINUTES);
+
+}

Added: james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/guava/GuavaCacheWrapper.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/guava/GuavaCacheWrapper.java?rev=1476501&view=auto
==============================================================================
--- james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/guava/GuavaCacheWrapper.java
(added)
+++ james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/guava/GuavaCacheWrapper.java
Sat Apr 27 06:33:50 2013
@@ -0,0 +1,37 @@
+package org.apache.mailbox.caching.guava;
+
+import org.apache.mailbox.caching.CacheLoaderFromUnderlying;
+
+import com.google.common.cache.Cache;
+
+public abstract class GuavaCacheWrapper<Key, Value, Underlying, KeyRepresentation, Except
extends Throwable>
+	implements CacheLoaderFromUnderlying<Key, Value, Underlying, Except> {
+
+	private final Cache<KeyRepresentation, Value> cache;
+//	private final CacheLoaderFromUnderlying<Key, Value, Underlying, Except> loader;
+
+	public GuavaCacheWrapper(Cache<KeyRepresentation, Value> cache/*, CacheLoaderFromUnderlying<Key,
Value, Underlying, Except> loader*/) {
+		this.cache = cache;
+//		this.loader = loader;
+	}
+	
+	public Value get(Key key, Underlying underlying) throws Except {
+		Value value = cache.getIfPresent(getKeyRepresentation(key));
+		if (value != null)
+			return value;
+		else {
+			value = load(key, underlying);
+			cache.put(getKeyRepresentation(key), value);
+			return value;
+		}
+
+	}
+	
+	public void invalidate(Key key) {
+		if (key != null) //needed?
+			cache.invalidate(getKeyRepresentation(key));
+	}
+
+	public abstract KeyRepresentation getKeyRepresentation(Key key);
+
+}

Added: james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/guava/GuavaMailboxByPathCache.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/guava/GuavaMailboxByPathCache.java?rev=1476501&view=auto
==============================================================================
--- james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/guava/GuavaMailboxByPathCache.java
(added)
+++ james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/guava/GuavaMailboxByPathCache.java
Sat Apr 27 06:33:50 2013
@@ -0,0 +1,80 @@
+package org.apache.mailbox.caching.guava;
+
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.exception.MailboxNotFoundException;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.store.mail.MailboxMapper;
+import org.apache.james.mailbox.store.mail.model.Mailbox;
+import org.apache.mailbox.caching.MailboxByPathCache;
+
+import com.google.common.cache.Cache;
+
+public class GuavaMailboxByPathCache<Id> extends AbstractGuavaCache implements MailboxByPathCache<Id>
{
+	
+	private final Cache<String, Mailbox<Id>> findMailboxByPathCache = BUILDER.build();
+
+	private final MailboxByPathCacheWrapper wrapper;
+
+	public GuavaMailboxByPathCache() {
+		this.wrapper = new MailboxByPathCacheWrapper(findMailboxByPathCache);
+	}
+	
+	@Override
+	public Mailbox<Id> findMailboxByPath(MailboxPath mailboxName, MailboxMapper<Id>
underlying) throws MailboxNotFoundException, MailboxException {
+		
+		return wrapper.get(mailboxName, underlying);
+	}
+	
+//	alternative plain implementation - review and choose the better
+//	public Mailbox<Id> findMailboxByPath(MailboxPath mailboxName, MailboxMapper<Id>
underlying) throws MailboxNotFoundException, MailboxException {
+//		Mailbox<Id> mailbox = findMailboxByPathCache.getIfPresent(mailboxName.toString());
+//		if (mailbox != null)
+//			return mailbox;
+//		else {
+//			mailbox = new MailboxByPathCacheLoaderFromUnderlying().load(mailboxName, underlying);
+//			findMailboxByPathCache.put(mailboxName.toString(), mailbox);
+//			return mailbox;
+//		}
+//	}
+
+	
+
+	@Override
+	public void invalidate(Mailbox<Id> mailbox) {
+		invalidate(new MailboxPath(mailbox.getNamespace(), mailbox.getUser(), mailbox.getName()));
+	}
+	
+	@Override
+	public void invalidate(MailboxPath mailboxPath) {
+		wrapper.invalidate(mailboxPath);
+	}
+
+
+	//Does it make sense to define such loaders as separate classes for reuse?
+//	class MailboxByPathCacheLoaderFromUnderlying implements CacheLoaderFromUnderlying<MailboxPath,
Mailbox<Id>, MailboxMapper<Id>, MailboxException> {
+//		@Override
+//		public Mailbox<Id> load(MailboxPath mailboxName, MailboxMapper<Id> underlying)
throws MailboxException {
+//			return underlying.findMailboxByPath(mailboxName);
+//		}
+//	}
+
+	class MailboxByPathCacheWrapper extends GuavaCacheWrapper<MailboxPath, Mailbox<Id>,
MailboxMapper<Id>, String, MailboxException> {
+
+		public MailboxByPathCacheWrapper(
+				Cache<String, Mailbox<Id>> cache/*,
+				MailboxByPathCacheLoaderFromUnderlying loader*/) {
+			super(cache);
+		}
+
+		@Override
+		public Mailbox<Id> load(MailboxPath mailboxName, MailboxMapper<Id> underlying)
throws MailboxException {
+			return underlying.findMailboxByPath(mailboxName);
+		}
+
+		@Override
+		public String getKeyRepresentation(MailboxPath key) {
+			return key.toString();
+		}
+		
+	}
+}

Added: james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/guava/GuavaMailboxMetadataCache.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/guava/GuavaMailboxMetadataCache.java?rev=1476501&view=auto
==============================================================================
--- james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/guava/GuavaMailboxMetadataCache.java
(added)
+++ james/mailbox/trunk/caching/src/main/java/org/apache/mailbox/caching/guava/GuavaMailboxMetadataCache.java
Sat Apr 27 06:33:50 2013
@@ -0,0 +1,135 @@
+package org.apache.mailbox.caching.guava;
+
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.store.mail.MessageMapper;
+import org.apache.james.mailbox.store.mail.model.Mailbox;
+import org.apache.mailbox.caching.MailboxMetadataCache;
+
+import com.google.common.cache.Cache;
+
+public class GuavaMailboxMetadataCache<Id> extends AbstractGuavaCache implements MailboxMetadataCache<Id>
{
+
+	// TODO these can probably be instantiated more elegant way
+	private final Cache<Id, Long> cacheCountMessagesInMailbox = BUILDER.build();
+	private final Cache<Id, Long> cacheCountUnseenMessagesInMailbox = BUILDER.build();
+	private final Cache<Id, Long> cacheFindFirstUnseenMessageUid = BUILDER.build();
+	private final Cache<Id, Long> cacheGetLastUid = BUILDER.build();
+	private final Cache<Id, Long> cacheGetHighestModSeq = BUILDER.build();
+
+	private final MetadataCacheWrapper countMessagesInMailboxWrapper = new CountMessagesInMailboxWrapper(cacheCountMessagesInMailbox);
+	private final MetadataCacheWrapper countUnseenMessagesInMailboxWrapper = new CountUnseenMessagesInMailboxWrapper(cacheCountUnseenMessagesInMailbox);
+	private final MetadataCacheWrapper findFirstUnseenMessageUid = new FindFirstUnseenMessageUidWrapper(cacheFindFirstUnseenMessageUid);
+	private final MetadataCacheWrapper highestModSeqWrapper = new HighestModseqCacheWrapper(cacheGetHighestModSeq);
+	private final MetadataCacheWrapper lastUidWrapper = new LastUidCacheWrapper(cacheGetLastUid);
+	
+	@Override
+	public long countMessagesInMailbox(Mailbox<Id> mailbox, MessageMapper<Id> underlying)
throws MailboxException {
+		return countMessagesInMailboxWrapper.get(mailbox, underlying);
+	}
+	
+	@Override
+	public long countUnseenMessagesInMailbox(Mailbox<Id> mailbox, MessageMapper<Id>
underlying)
+			throws MailboxException {
+		return countUnseenMessagesInMailboxWrapper.get(mailbox, underlying);
+	}
+	
+	@Override
+	public Long findFirstUnseenMessageUid(Mailbox<Id> mailbox, MessageMapper<Id>
underlying)
+			throws MailboxException {
+		return findFirstUnseenMessageUid.get(mailbox, underlying);
+	}
+	
+	@Override
+	public long getLastUid(Mailbox<Id> mailbox, MessageMapper<Id> underlying) throws
MailboxException {
+		return lastUidWrapper.get(mailbox, underlying);
+
+	}
+	
+	@Override
+	public long getHighestModSeq(Mailbox<Id> mailbox, MessageMapper<Id> underlying)
throws MailboxException {
+		return highestModSeqWrapper.get(mailbox, underlying);
+	}
+	
+	@Override
+	public void invalidate(Mailbox<Id> mailbox) {
+		cacheCountMessagesInMailbox.invalidate(mailbox);
+		cacheCountUnseenMessagesInMailbox.invalidate(mailbox);
+		cacheFindFirstUnseenMessageUid.invalidate(mailbox);
+		lastUidWrapper.invalidate(mailbox);
+		highestModSeqWrapper.invalidate(mailbox);
+	}
+
+	
+	abstract class MetadataCacheWrapper extends GuavaCacheWrapper<Mailbox<Id>, Long,
MessageMapper<Id>, Id, MailboxException> {
+
+		public MetadataCacheWrapper(Cache<Id, Long> cache) {
+			super(cache);
+		}
+
+		@Override
+		public Id getKeyRepresentation(Mailbox<Id> key) {
+			return key.getMailboxId();
+		}		
+		
+	}
+
+	class CountMessagesInMailboxWrapper extends MetadataCacheWrapper {
+
+		public CountMessagesInMailboxWrapper(Cache<Id, Long> cache) {
+			super(cache);
+		}
+		@Override
+		public Long load(Mailbox<Id> mailbox, MessageMapper<Id> underlying)
+				throws MailboxException {
+			return underlying.countMessagesInMailbox(mailbox);
+		}
+
+	}
+	
+	class CountUnseenMessagesInMailboxWrapper extends MetadataCacheWrapper {
+
+		public CountUnseenMessagesInMailboxWrapper(Cache<Id, Long> cache) {
+			super(cache);
+		}
+		@Override
+		public Long load(Mailbox<Id> mailbox, MessageMapper<Id> underlying)
+				throws MailboxException {
+			return underlying.countUnseenMessagesInMailbox(mailbox);
+		}
+
+	}
+
+	class FindFirstUnseenMessageUidWrapper extends MetadataCacheWrapper {
+
+		public FindFirstUnseenMessageUidWrapper(Cache<Id, Long> cache) {
+			super(cache);
+		}
+		@Override
+		public Long load(Mailbox<Id> mailbox, MessageMapper<Id> underlying)
+				throws MailboxException {
+			return underlying.findFirstUnseenMessageUid(mailbox);
+		}
+
+	}
+
+	class LastUidCacheWrapper extends MetadataCacheWrapper {
+		public LastUidCacheWrapper(Cache<Id, Long> cache) {
+			super(cache);
+		}
+		@Override
+		public Long load(Mailbox<Id> mailbox, MessageMapper<Id> underlying) throws
MailboxException {
+			return underlying.getLastUid(mailbox);
+		}
+	}
+
+	class HighestModseqCacheWrapper extends MetadataCacheWrapper {
+		public HighestModseqCacheWrapper(Cache<Id, Long> cache) {
+			super(cache);
+		}
+		@Override
+		public Long load(Mailbox<Id> mailbox, MessageMapper<Id> underlying) throws
MailboxException {
+			return underlying.getHighestModSeq(mailbox);
+		}
+	}
+
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


Mime
View raw message