Added: james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/AbstractLockingUidProvider.java URL: http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/AbstractLockingUidProvider.java?rev=1139535&view=auto ============================================================================== --- james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/AbstractLockingUidProvider.java (added) +++ james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/AbstractLockingUidProvider.java Sat Jun 25 12:29:24 2011 @@ -0,0 +1,49 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ +package org.apache.james.mailbox.store.mail; + +import org.apache.james.mailbox.MailboxException; +import org.apache.james.mailbox.MailboxPathLocker; +import org.apache.james.mailbox.MailboxPathLocker.LockAwareExecution; +import org.apache.james.mailbox.MailboxSession; +import org.apache.james.mailbox.store.StoreMailboxPath; +import org.apache.james.mailbox.store.mail.model.Mailbox; + +public abstract class AbstractLockingUidProvider<Id> implements UidProvider<Id>{ + + private final MailboxPathLocker locker; + + public AbstractLockingUidProvider(MailboxPathLocker locker) { + this.locker = locker; + } + + @Override + public long nextUid(final MailboxSession session, final Mailbox<Id> mailbox) throws MailboxException { + return locker.executeWithLock(session, new StoreMailboxPath<Id>(mailbox), new LockAwareExecution<Long>() { + + @Override + public Long execute() throws MailboxException { + return lockedNextUid(session, mailbox); + } + }); + } + + protected abstract long lockedNextUid(MailboxSession session, Mailbox<Id> mailbox) throws MailboxException; + +}
Modified: james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/AbstractMessageMapper.java URL: http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/AbstractMessageMapper.java?rev=1139535&r1=1139534&r2=1139535&view=diff ============================================================================== --- james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/AbstractMessageMapper.java (original) +++ james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/AbstractMessageMapper.java Sat Jun 25 12:29:24 2011 @@ -21,9 +21,6 @@ package org.apache.james.mailbox.store.m import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicLong; import javax.mail.Flags; @@ -43,13 +40,15 @@ import org.apache.james.mailbox.store.tr * @param <Id> */ public abstract class AbstractMessageMapper<Id> extends TransactionalMapper implements MessageMapper<Id>{ - - private final static ConcurrentHashMap<Object, AtomicLong> seqs = new ConcurrentHashMap<Object, AtomicLong>(); - private final static ConcurrentHashMap<Object, AtomicLong> uids = new ConcurrentHashMap<Object, AtomicLong>(); + protected final MailboxSession mailboxSession; + private final UidProvider<Id> uidProvider; + private final ModSeqProvider<Id> modSeqProvider; - public AbstractMessageMapper(MailboxSession mailboxSession) { + public AbstractMessageMapper(MailboxSession mailboxSession, UidProvider<Id> uidProvider, ModSeqProvider<Id> modSeqProvider) { this.mailboxSession = mailboxSession; + this.uidProvider = uidProvider; + this.modSeqProvider = modSeqProvider; } @@ -58,7 +57,7 @@ public abstract class AbstractMessageMap * @see org.apache.james.mailbox.store.mail.MessageMapper#getHighestModSeq(org.apache.james.mailbox.store.mail.model.Mailbox) */ public long getHighestModSeq(Mailbox<Id> mailbox) throws MailboxException { - return retrieveLastUsedModSeq(mailbox).get(); + return modSeqProvider.highestModSeq(mailboxSession, mailbox); } /* @@ -66,102 +65,10 @@ public abstract class AbstractMessageMap * @see org.apache.james.mailbox.store.mail.MessageMapper#getLastUid(org.apache.james.mailbox.store.mail.model.Mailbox) */ public long getLastUid(Mailbox<Id> mailbox) throws MailboxException { - return retrieveLastUid(mailbox).get(); - } - - - private long nextUid(Mailbox<Id> mailbox) throws MailboxException { - return retrieveLastUid(mailbox).incrementAndGet(); + return uidProvider.lastUid(mailboxSession, mailbox); } - - /** - * Return the next mod-seq which can be used while append a Message to the {@link Mailbox}. - * Its important that the returned mod-seq is higher then the last used and that the next call of this method does not return the same mod-swq. - * - * @param mailbox - * @return nextUid - * @throws MailboxException - */ - private long nextModSeq(Mailbox<Id> mailbox) throws MailboxException { - return retrieveLastUsedModSeq(mailbox).incrementAndGet(); - } - - /** - * Retrieve the last used mod-seq for the {@link Mailbox} from cache or via lazy lookup. - * - * @param session - * @param mailbox - * @return lastModSeq - * @throws MailboxException - */ - protected AtomicLong retrieveLastUsedModSeq(Mailbox<Id> mailbox) throws MailboxException { - AtomicLong seq = seqs.get(mailbox.getMailboxId()); - - if (seq == null) { - seq = new AtomicLong(higestModSeq(mailbox)); - AtomicLong cachedSeq = seqs.putIfAbsent(mailbox.getMailboxId(), seq); - if (cachedSeq != null) { - seq = cachedSeq; - } - } - - return seq; - } - - private long higestModSeq(Mailbox<Id> mailbox) throws MailboxException { - long modSeq = calculateHigestModSeq(mailbox); - if (modSeq < 1) { - modSeq = mailbox.getHighestKnownModSeq(); - } - return modSeq; - } - - /** - * Retrieve the last uid for the {@link Mailbox} from cache or via lazy lookup. - * - * @param mailbox - * @return lastUid - * @throws MailboxException - */ - protected AtomicLong retrieveLastUid(Mailbox<Id> mailbox) throws MailboxException { - AtomicLong uid = uids.get(mailbox.getMailboxId()); - - if (uid == null) { - uid = new AtomicLong(lastUid(mailbox)); - AtomicLong cachedUid = uids.putIfAbsent(mailbox.getMailboxId(), uid); - if (cachedUid != null) { - uid = cachedUid; - } - } - - return uid; - } - - private long lastUid(Mailbox<Id> mailbox) throws MailboxException { - long uid = calculateLastUid(mailbox); - if (uid < 1) { - uid = mailbox.getLastKnownUid(); - } - return uid; - } - - /* - * (non-Javadoc) - * @see org.apache.james.mailbox.store.mail.MessageMapper#expungeMarkedForDeletionInMailbox(org.apache.james.mailbox.store.mail.model.Mailbox, org.apache.james.mailbox.MessageRange) - */ - public Map<Long, MessageMetaData> expungeMarkedForDeletionInMailbox(Mailbox<Id> mailbox, MessageRange set) throws MailboxException { - Map<Long, MessageMetaData> data = expungeMarkedForDeletion(mailbox, set); - if (data.isEmpty() == false) { - - // Increase the mod-sequence and save it with the uid for this mailbox in a permanent way - // See MAILBOX-75 - saveSequences(mailbox, getLastUid(mailbox), nextModSeq(mailbox)); - - } - return data; - } /* @@ -176,7 +83,10 @@ public abstract class AbstractMessageMap long modSeq = -1; if (members.isEmpty() == false) { - modSeq = nextModSeq(mailbox); + // if a mailbox does not support mod-sequences the provider may be null + if (modSeqProvider != null) { + modSeq = modSeqProvider.nextModSeq(mailboxSession, mailbox); + } } for (final Message<Id> member : members) { Flags originalFlags = member.createFlags(); @@ -217,8 +127,12 @@ public abstract class AbstractMessageMap * @see org.apache.james.mailbox.store.mail.MessageMapper#add(org.apache.james.mailbox.store.mail.model.Mailbox, org.apache.james.mailbox.store.mail.model.Message) */ public MessageMetaData add(final Mailbox<Id> mailbox, Message<Id> message) throws MailboxException { - message.setUid(nextUid(mailbox)); - message.setModSeq(nextModSeq(mailbox)); + message.setUid(uidProvider.nextUid(mailboxSession, mailbox)); + + // if a mailbox does not support mod-sequences the provider may be null + if (modSeqProvider != null) { + message.setModSeq(modSeqProvider.nextModSeq(mailboxSession, mailbox)); + } MessageMetaData data = save(mailbox, message); return data; @@ -231,35 +145,17 @@ public abstract class AbstractMessageMap * @see org.apache.james.mailbox.store.mail.MessageMapper#copy(org.apache.james.mailbox.store.mail.model.Mailbox, org.apache.james.mailbox.store.mail.model.Message) */ public MessageMetaData copy(final Mailbox<Id> mailbox, final Message<Id> original) throws MailboxException { - long uid = nextUid(mailbox); - long modSeq = nextModSeq(mailbox); + long uid = uidProvider.nextUid(mailboxSession, mailbox); + long modSeq = -1; + if (modSeqProvider != null) { + modSeq = modSeqProvider.nextModSeq(mailboxSession, mailbox); + } final MessageMetaData metaData = copy(mailbox, uid, modSeq, original); return metaData; } - - /** - * Return the higest mod-seq for the given {@link Mailbox}. This method is called in a lazy fashion. So when the first mod-seq is needed for a {@link Mailbox} - * it will get called to get the higest used. After that it will stored in memory and just increment there on each {@link #nextModSeq(MailboxSession, Mailbox)} call. - * - * @param mailbox - * @return lastUid - * @throws MailboxException - */ - protected abstract long calculateHigestModSeq(Mailbox<Id> mailbox) throws MailboxException; - - /** - * Return the last used uid for the given {@link Mailbox}. This method is called in a lazy fashion. So when the first uid is needed for a {@link Mailbox} - * it will get called to get the last used. After that it will stored in memory and just increment there on each {@link #nextUid(MailboxSession, Mailbox)} call. - * - * @param session - * @param mailbox - * @return lastUid - * @throws MailboxException - */ - protected abstract long calculateLastUid(Mailbox<Id> mailbox) throws MailboxException; /** @@ -285,25 +181,4 @@ public abstract class AbstractMessageMap */ protected abstract MessageMetaData copy(Mailbox<Id> mailbox, long uid, long modSeq, Message<Id> original) throws MailboxException; - - /** - * Expunge all Messages which are marked for deletion - * - * @param mailbox - * @param set - * @return - * @throws MailboxException - */ - protected abstract Map<Long, MessageMetaData> expungeMarkedForDeletion(Mailbox<Id> mailbox, MessageRange set) throws MailboxException; - - /** - * Save the sequence meta-data for the mailbox in a permanent way - * - * @param mailbox - * @param lastUid - * @param highestModSeq - * @throws MailboxException - */ - protected abstract void saveSequences(Mailbox<Id> mailbox, long lastUid, long highestModSeq) throws MailboxException; - } Added: james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/ModSeqProvider.java URL: http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/ModSeqProvider.java?rev=1139535&view=auto ============================================================================== --- james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/ModSeqProvider.java (added) +++ james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/ModSeqProvider.java Sat Jun 25 12:29:24 2011 @@ -0,0 +1,55 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ +package org.apache.james.mailbox.store.mail; + +import org.apache.james.mailbox.MailboxException; +import org.apache.james.mailbox.MailboxSession; +import org.apache.james.mailbox.store.mail.model.Mailbox; + +/** + * Take care of provide mod-seqences for a given {@link Mailbox}. Be aware that implementations + * need to be thread-safe! + * + * + * @param <Id> + */ +public interface ModSeqProvider<Id> { + + /** + * Return the next mod-sequence which can be used for the {@link Mailbox}. + * Its important that the returned mod-sequence is higher then the last used and that the next call of this method does return a higher + * one + * + * @param session + * @param mailbox + * @return modSeq + * @throws MailboxException + */ + public long nextModSeq(MailboxSession session, Mailbox<Id> mailbox) throws MailboxException; + + /** + * Return the highest mod-sequence which were used for the {@link Mailbox} + * + * @param session + * @param mailbox + * @return highest + * @throws MailboxException + */ + public long highestModSeq(MailboxSession session, Mailbox<Id> mailbox) throws MailboxException; +} Added: james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/UidProvider.java URL: http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/UidProvider.java?rev=1139535&view=auto ============================================================================== --- james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/UidProvider.java (added) +++ james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/UidProvider.java Sat Jun 25 12:29:24 2011 @@ -0,0 +1,55 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ +package org.apache.james.mailbox.store.mail; + +import org.apache.james.mailbox.MailboxException; +import org.apache.james.mailbox.MailboxSession; +import org.apache.james.mailbox.store.mail.model.Mailbox; + +/** + * Take care of provide uids for a given {@link Mailbox}. Be aware that implementations + * need to be thread-safe! + * + * + * @param <Id> + */ +public interface UidProvider<Id> { + + /** + * Return the next uid which can be used while append a Message to the {@link Mailbox}. + * Its important that the returned uid is higher then the last used and that the next call of this method does return a higher + * one + * + * @param session + * @param mailbox + * @return nextUid + * @throws MailboxException + */ + public long nextUid(MailboxSession session, Mailbox<Id> mailbox) throws MailboxException; + + /** + * Return the last uid which were used for storing a Message in the {@link Mailbox} + * + * @param session + * @param mailbox + * @return lastUid + * @throws MailboxException + */ + public long lastUid(MailboxSession session, Mailbox<Id> mailbox) throws MailboxException; +} Modified: james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/model/Mailbox.java URL: http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/model/Mailbox.java?rev=1139535&r1=1139534&r2=1139535&view=diff ============================================================================== --- james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/model/Mailbox.java (original) +++ james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/model/Mailbox.java Sat Jun 25 12:29:24 2011 @@ -70,22 +70,4 @@ public interface Mailbox<Id> { * @return uid validity */ long getUidValidity(); - - /** - * Return the last known uid for this mailbox which - * was stored in a persist way. This does not guaranteer - * that there is no "higher" uid already allocated - * - * @return lastKnownUid - */ - long getLastKnownUid(); - - /** - * Return the highest known mod-seq for this mailbox which - * was stored in a persist way. This does not guaranteer - * that there is no "higher" mod-seq already allocated - * - * @return highestKnownModSeq - */ - long getHighestKnownModSeq(); } \ No newline at end of file Modified: james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailbox.java URL: http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailbox.java?rev=1139535&r1=1139534&r2=1139535&view=diff ============================================================================== --- james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailbox.java (original) +++ james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailbox.java Sat Jun 25 12:29:24 2011 @@ -28,16 +28,12 @@ public class SimpleMailbox<Id> implement private String user; private String name; private long uidValidity; - private long lastKnownUid; - private long highestKnownModSeq; - public SimpleMailbox(MailboxPath path, long uidValidity, long lastKnownUid, long highestKnownModSeq) { + public SimpleMailbox(MailboxPath path, long uidValidity) { this.namespace = path.getNamespace(); this.user = path.getUser(); this.name = path.getName(); this.uidValidity = uidValidity; - this.lastKnownUid = lastKnownUid; - this.highestKnownModSeq = highestKnownModSeq; } public SimpleMailbox(Mailbox<Id> mailbox) { @@ -46,8 +42,6 @@ public class SimpleMailbox<Id> implement this.user = mailbox.getUser(); this.name = mailbox.getName(); this.uidValidity = mailbox.getUidValidity(); - this.lastKnownUid = mailbox.getLastKnownUid(); - this.highestKnownModSeq = mailbox.getHighestKnownModSeq(); } /* @@ -165,21 +159,6 @@ public class SimpleMailbox<Id> implement return namespace + ":" + user + ":" + name; } - /* - * (non-Javadoc) - * @see org.apache.james.mailbox.store.mail.model.Mailbox#getLastKnownUid() - */ - public long getLastKnownUid() { - return lastKnownUid; - } - - /* - * (non-Javadoc) - * @see org.apache.james.mailbox.store.mail.model.Mailbox#getHighestKnownModSeq() - */ - public long getHighestKnownModSeq() { - return highestKnownModSeq; - } public void setMailboxId(Id id) { this.id = id; Modified: james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/MailboxEventDispatcherFlagsTest.java URL: http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/MailboxEventDispatcherFlagsTest.java?rev=1139535&r1=1139534&r2=1139535&view=diff ============================================================================== --- james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/MailboxEventDispatcherFlagsTest.java (original) +++ james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/MailboxEventDispatcherFlagsTest.java Sat Jun 25 12:29:24 2011 @@ -102,16 +102,6 @@ public class MailboxEventDispatcherFlags public long getUidValidity() { return 0; } - - @Override - public long getLastKnownUid() { - return 0; - } - - @Override - public long getHighestKnownModSeq() { - return 0; - } }; @Before --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org