use of com.zimbra.cs.purge.PurgeFromIncomingDataSource in project zm-mailbox by Zimbra.
the class MailItemImport method purgeIfNecessary.
protected void purgeIfNecessary(OperationContext octxt, CurrentUsage usage, ParsedMessage pm) throws ServiceException {
if (!mbox.getAccount().isFeatureDataSourcePurgingEnabled()) {
return;
}
if (usage == null) {
usage = new CurrentUsage();
}
// first, see if the incoming message is part of an existing conversation thread
Integer thisConvId = null;
if (pm != null) {
List<Conversation> matchingConvs = mbox.lookupConversation(pm);
if (matchingConvs.size() > 0) {
Collections.sort(matchingConvs, new MailItem.SortSizeDescending());
thisConvId = matchingConvs.remove(0).getId();
}
// from the purge queue
if (thisConvId != null) {
if (thisConvId < 0) {
// the incoming message is the second message in a conversation, so the PurgeableConv entry in the queue
// will be under the ID of the first message
ConversationPurgeQueue.removeAllNodesById(-1 * thisConvId);
} else {
// the incoming message is part of a conversation that already has a dedicated ID, so the PurgeableConv
// entry will be under the ID of the conversation
ConversationPurgeQueue.removeAllNodesById(thisConvId);
}
}
}
if (usage.spaceToFreeUp > 0 && !usage.sizeOverQuota) {
// see if a purge process is already running
PurgeLock purgeLock = getPurgeLock(mbox.getAccount());
try {
synchronized (purgeLock) {
if (purgeLock.isLocked()) {
//wait and acquire purge lock
purgeLock.lock();
//wait and acquire purge lock
;
//could have changed since previous purge
usage.calculate();
if (usage.spaceToFreeUp <= 0) {
return;
}
} else {
purgeLock.lock();
}
}
DataSourcePurge purge;
if (usage.overTotalQuota) {
purge = new PurgeFromAllDataSources(mbox);
} else {
purge = new PurgeFromIncomingDataSource(mbox);
}
purge.purgeConversations(octxt, dataSource, usage.spaceToFreeUp, thisConvId);
usage.calculate();
int attempt = 0;
while (usage.spaceToFreeUp > 0 && !usage.sizeOverQuota && attempt < MAX_PURGE_ATTEMPTS) {
attempt++;
// This is possible in some edge cases, such as when some purged conversations
// spanned multiple data sources, which would make the actual purged size less than
// the conversation size.
ZimbraLog.datasource.warn(String.format("still need to free up %d bytes!", usage.spaceToFreeUp));
purge.purgeConversations(octxt, dataSource, usage.spaceToFreeUp, thisConvId);
usage.calculate();
}
} finally {
purgeLock.unlock();
}
}
}
Aggregations