Search in sources :

Example 26 with MailboxBlob

use of com.zimbra.cs.store.MailboxBlob in project zm-mailbox by Zimbra.

the class MailItem method copy.

/** Copies an item to a {@link Folder}.  Persists the new item to the
     *  database and the in-memory cache.  Copies to the same folder as the
     *  original item will succeed.<p>
     *
     *  Immutable copied items (both the original and the target) share the
     *  same entry in the index and get the {@link Flag#BITMASK_COPIED} flag to
     *  facilitate garbage collection of index entries.  (Mutable copied items
     *  are indexed separately.)  They do not share the same blob on disk,
     *  although the system will use a hard link where possible.  Copying a
     *  {@link Message} will put it in the same {@link Conversation} as the
     *  original (exceptions: draft messages, messages in the Junk folder).
     *
     * @param folder    The folder to copy the item to.
     * @param copyId    The item id for the newly-created copy.
     * @param parent    The target parent MailItem for the new copy.
     * @perms {@link ACL#RIGHT_INSERT} on the target folder,
     *        {@link ACL#RIGHT_READ} on the original item
     * @throws ServiceException  The following error codes are possible:<ul>
     *    <li><tt>mail.CANNOT_COPY</tt> - if the item is not copyable
     *    <li><tt>mail.CANNOT_CONTAIN</tt> - if the target folder can't hold
     *        the copy of the item
     *    <li><tt>service.FAILURE</tt> - if there's a database failure
     *    <li><tt>service.PERM_DENIED</tt> - if you don't have sufficient
     *        permissions</ul> */
MailItem copy(Folder folder, int copyId, String copyUuid, MailItem parent) throws IOException, ServiceException {
    if (!isCopyable())
        throw MailServiceException.CANNOT_COPY(mId);
    if (!folder.canContain(this))
        throw MailServiceException.CANNOT_CONTAIN();
    if (!canAccess(ACL.RIGHT_READ))
        throw ServiceException.PERM_DENIED("you do not have the required rights on the item");
    if (!folder.canAccess(ACL.RIGHT_INSERT))
        throw ServiceException.PERM_DENIED("you do not have the required rights on the target folder");
    // We'll share the index entry if this item can't change out from under us. Re-index the copy if existing item
    // (a) wasn't indexed or (b) is mutable or (c) existing item is in dumpster (which implies copy is not in
    // dumpster)
    boolean inDumpster = inDumpster();
    boolean shareIndex = !inDumpster && !isMutable() && getIndexStatus() == IndexStatus.DONE && !folder.inSpam();
    // if the copy or original is in Spam, put the copy in its own conversation
    boolean detach = parent == null || isTagged(Flag.FlagInfo.DRAFT) || inSpam() != folder.inSpam();
    parent = detach ? null : parent;
    if (shareIndex && !isTagged(Flag.FlagInfo.COPIED)) {
        alterSystemFlag(mMailbox.getFlagById(Flag.ID_COPIED), true);
        if (ZimbraLog.mailop.isDebugEnabled()) {
            ZimbraLog.mailop.debug("setting copied flag for %s", getMailopContext(this));
        }
    }
    StoreManager sm = StoreManager.getInstance();
    // main item
    String locator = null;
    MailboxBlob srcMblob = getBlob();
    if (srcMblob != null) {
        MailboxBlob mblob = sm.copy(srcMblob, mMailbox, copyId, mMailbox.getOperationChangeID());
        mMailbox.markOtherItemDirty(mblob);
        locator = mblob.getLocator();
    }
    UnderlyingData data = mData.duplicate(copyId, copyUuid, folder.getId(), locator);
    data.parentId = detach ? -1 : parent.mId;
    data.indexId = shareIndex ? getIndexId() : IndexStatus.DEFERRED.id();
    if (!shareIndex) {
        data.unsetFlag(Flag.FlagInfo.COPIED);
    }
    // The copy is never in dumpster.
    data.unsetFlag(Flag.FlagInfo.IN_DUMPSTER);
    data.metadata = encodeMetadata().toString();
    data.contentChanged(mMailbox);
    ZimbraLog.mailop.info("Copying %s: copyId=%d, folderId=%d, folderName=%s, parentId=%d.", getMailopContext(this), copyId, folder.getId(), folder.getName(), data.parentId);
    String prevFolders = DbMailItem.copy(this, copyId, copyUuid, folder, data.indexId, data.parentId, data.locator, data.metadata, inDumpster);
    if (!StringUtil.isNullOrEmpty(prevFolders)) {
        data.setPrevFolders(prevFolders);
    }
    if (this instanceof CalendarItem)
        DbMailItem.copyCalendarItem((CalendarItem) this, copyId, inDumpster);
    // it is never desirable to copy old revisions. (bug 55070)
    if (inDumpster) {
        for (MailItem revision : loadRevisions()) {
            MailboxBlob srcRevBlob = revision.getBlob();
            String revLocator = null;
            if (srcRevBlob != null) {
                MailboxBlob copyRevBlob = sm.copy(srcRevBlob, mMailbox, copyId, revision.getSavedSequence());
                mMailbox.markOtherItemDirty(copyRevBlob);
                revLocator = copyRevBlob.getLocator();
            }
            DbMailItem.copyRevision(revision, copyId, revLocator, inDumpster);
        }
    }
    MailItem copy = constructItem(mMailbox, data);
    copy.finishCreation(parent);
    if (!shareIndex) {
        mMailbox.index.add(copy);
    }
    return copy;
}
Also used : DbMailItem(com.zimbra.cs.db.DbMailItem) MailboxBlob(com.zimbra.cs.store.MailboxBlob) StoreManager(com.zimbra.cs.store.StoreManager)

Example 27 with MailboxBlob

use of com.zimbra.cs.store.MailboxBlob in project zm-mailbox by Zimbra.

the class VerifyStoreManager method basicPerfTest.

private Stats basicPerfTest(int numBlobs, int blobSize, boolean checkBlobs) throws Exception {
    Mailbox mbox = MailboxManager.getInstance().getMailboxByAccount(AccountTestUtil.getAccount(USER_NAME));
    StoreManager sm = StoreManager.getInstance();
    List<ParsedMessage> msgs = new ArrayList<ParsedMessage>();
    int count = numBlobs;
    for (int i = 0; i < count; i++) {
        msgs.add(getMessage(blobSize));
    }
    List<Blob> incoming = new ArrayList<Blob>();
    ZimbraLog.store.info("starting store incoming loop");
    long start = System.currentTimeMillis();
    for (ParsedMessage msg : msgs) {
        incoming.add(sm.storeIncoming(msg.getRawInputStream()));
    }
    long incomingTime = System.currentTimeMillis() - start;
    List<StagedBlob> staged = new ArrayList<StagedBlob>();
    ZimbraLog.store.info("starting stage loop");
    start = System.currentTimeMillis();
    for (Blob blob : incoming) {
        staged.add(sm.stage(blob, mbox));
    }
    long stageTime = System.currentTimeMillis() - start;
    List<MailboxBlob> linked = new ArrayList<MailboxBlob>();
    ZimbraLog.store.info("starting link loop");
    start = System.currentTimeMillis();
    //fake itemId, never use this test with real userid
    int i = 0;
    for (StagedBlob blob : staged) {
        linked.add(sm.link(blob, mbox, i++, 1));
    }
    long linkTime = System.currentTimeMillis() - start;
    List<MailboxBlob> fetched = new ArrayList<MailboxBlob>();
    ZimbraLog.store.info("starting fetch loop");
    start = System.currentTimeMillis();
    i = 0;
    for (MailboxBlob mblob : linked) {
        fetched.add(sm.getMailboxBlob(mbox, i++, 1, mblob.getLocator()));
    }
    long fetchTime = System.currentTimeMillis() - start;
    if (checkBlobs) {
        for (i = 0; i < count; i++) {
            checkBlob(msgs.get(i), incoming.get(i), staged.get(i), linked.get(i), fetched.get(i), mbox);
        }
    }
    ZimbraLog.store.info("starting delete loop");
    start = System.currentTimeMillis();
    for (MailboxBlob mblob : fetched) {
        sm.delete(mblob);
    }
    long deleteTime = System.currentTimeMillis() - start;
    Stats stats = new Stats(numBlobs, incomingTime, stageTime, linkTime, fetchTime, deleteTime);
    return stats;
}
Also used : Blob(com.zimbra.cs.store.Blob) MailboxBlob(com.zimbra.cs.store.MailboxBlob) StagedBlob(com.zimbra.cs.store.StagedBlob) StagedBlob(com.zimbra.cs.store.StagedBlob) MailboxBlob(com.zimbra.cs.store.MailboxBlob) ParsedMessage(com.zimbra.cs.mime.ParsedMessage) ArrayList(java.util.ArrayList) StoreManager(com.zimbra.cs.store.StoreManager) Mailbox(com.zimbra.cs.mailbox.Mailbox)

Aggregations

MailboxBlob (com.zimbra.cs.store.MailboxBlob)27 StoreManager (com.zimbra.cs.store.StoreManager)16 StagedBlob (com.zimbra.cs.store.StagedBlob)14 Mailbox (com.zimbra.cs.mailbox.Mailbox)12 Blob (com.zimbra.cs.store.Blob)12 IOException (java.io.IOException)11 ServiceException (com.zimbra.common.service.ServiceException)8 ParsedMessage (com.zimbra.cs.mime.ParsedMessage)7 Test (org.junit.Test)7 ArrayList (java.util.ArrayList)6 InputStream (java.io.InputStream)5 TargetConstraint (com.zimbra.cs.mailbox.MailItem.TargetConstraint)4 CreateMountpoint (com.zimbra.cs.redolog.op.CreateMountpoint)4 AccountServiceException (com.zimbra.cs.account.AccountServiceException)3 DbMailItem (com.zimbra.cs.db.DbMailItem)3 DbTag (com.zimbra.cs.db.DbTag)3 IndexDocument (com.zimbra.cs.index.IndexDocument)3 MailServiceException (com.zimbra.cs.mailbox.MailServiceException)3 Message (com.zimbra.cs.mailbox.Message)3 NormalizedTags (com.zimbra.cs.mailbox.Tag.NormalizedTags)3