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;
}
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;
}
Aggregations