use of com.zimbra.cs.store.StoreManager in project zm-mailbox by Zimbra.
the class MailItem method icopy.
/** Copies the item to the target folder. Persists the new item to the
* database and the in-memory cache. Copies to the same folder as the
* original item will succeed, but it is strongly suggested that
* {@link #copy(Folder, int, int, short)} be used in that case.<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. Copied
* {@link Message}s are remain in the same {@link Conversation}, but the
* <b>original</b> Message is placed in a new {@link VirtualConversation}
* rather than being grouped with the copied Message.
*
* @param target The folder to copy the item to.
* @param copyId The item id for the newly-created 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 icopy(Folder target, int copyId, String copyUuid) throws IOException, ServiceException {
if (!isCopyable())
throw MailServiceException.CANNOT_COPY(mId);
if (!target.canContain(this))
throw MailServiceException.CANNOT_CONTAIN();
// permissions required are the same as for copy()
if (!canAccess(ACL.RIGHT_READ))
throw ServiceException.PERM_DENIED("you do not have the required rights on the item");
if (!target.canAccess(ACL.RIGHT_INSERT))
throw ServiceException.PERM_DENIED("you do not have the required rights on the target folder");
// fetch the parent *before* changing the DB
MailItem parent = getParent();
// first, copy the item to the target folder while setting:
// - FLAGS -> FLAGS | Flag.BITMASK_COPIED
// - INDEX_ID -> old index id
// - FOLDER_ID -> new folder
// - IMAP_ID -> new IMAP uid
// - VOLUME_ID -> target volume ID
// then, update the original item
// - PARENT_ID -> NULL
// - FLAGS -> FLAGS | Flag.BITMASK_COPIED
// finally, update OPEN_CONVERSATION if PARENT_ID was NULL
// - ITEM_ID = copy's id for hash
String locator = null;
MailboxBlob srcMblob = getBlob();
if (srcMblob != null) {
StoreManager sm = StoreManager.getInstance();
MailboxBlob mblob = sm.copy(srcMblob, mMailbox, copyId, mMailbox.getOperationChangeID());
mMailbox.markOtherItemDirty(mblob);
locator = mblob.getLocator();
}
// 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.
boolean shareIndex = !isMutable() && getIndexStatus() == IndexStatus.DONE && !target.inSpam();
UnderlyingData data = mData.duplicate(copyId, copyUuid, target.getId(), locator);
data.metadata = encodeMetadata().toString();
data.imapId = copyId;
data.indexId = shareIndex ? getIndexId() : IndexStatus.DEFERRED.id();
data.contentChanged(mMailbox);
ZimbraLog.mailop.info("Performing IMAP copy of %s: copyId=%d, folderId=%d, folderName=%s, parentId=%d.", getMailopContext(this), copyId, target.getId(), target.getName(), data.parentId);
DbMailItem.icopy(this, data, shareIndex);
MailItem copy = constructItem(mMailbox, data);
copy.finishCreation(null);
if (shareIndex && !isTagged(Flag.FlagInfo.COPIED)) {
Flag copiedFlag = mMailbox.getFlagById(Flag.ID_COPIED);
tagChanged(copiedFlag, true);
copy.tagChanged(copiedFlag, true);
if (parent != null)
parent.inheritedTagChanged(copiedFlag, true);
}
if (parent != null && parent.getId() > 0) {
markItemModified(Change.PARENT);
parent.markItemModified(Change.CHILDREN);
mData.parentId = mData.type == Type.MESSAGE.toByte() ? -mId : -1;
metadataChanged();
}
if (!shareIndex) {
mMailbox.index.add(copy);
}
return copy;
}
use of com.zimbra.cs.store.StoreManager 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.StoreManager in project zm-mailbox by Zimbra.
the class SaveDraft method redo.
@Override
public void redo() throws Exception {
Mailbox mbox = MailboxManager.getInstance().getMailboxById(getMailboxId());
StoreManager sm = StoreManager.getInstance();
Blob blob = null;
InputStream in = null;
try {
in = mData.getInputStream();
if (mData.getLength() != mMsgSize)
in = new GZIPInputStream(in);
blob = sm.storeIncoming(in);
ParsedMessage pm = new ParsedMessage(blob.getFile(), getTimestamp(), mbox.attachmentsIndexingEnabled());
mbox.saveDraft(getOperationContext(), pm, getMessageId());
} finally {
ByteUtil.closeStream(in);
sm.quietDelete(blob);
}
}
use of com.zimbra.cs.store.StoreManager 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