package com.mongodb.connection;
import com.mongodb.MongoBulkWriteException;
import com.mongodb.ServerAddress;
import com.mongodb.WriteConcern;
import com.mongodb.bulk.BulkWriteError;
import com.mongodb.bulk.BulkWriteResult;
import com.mongodb.bulk.BulkWriteUpsert;
import com.mongodb.bulk.WriteConcernError;
import com.mongodb.internal.connection.IndexMap;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import static com.mongodb.assertions.Assertions.notNull;
import static java.util.Arrays.asList;
@Deprecated
public class BulkWriteBatchCombiner {
private final ServerAddress serverAddress;
private final boolean ordered;
private final WriteConcern writeConcern;
private int insertedCount;
private int matchedCount;
private int deletedCount;
private int modifiedCount = 0;
private final Set<BulkWriteUpsert> writeUpserts = new TreeSet<BulkWriteUpsert>(new Comparator<BulkWriteUpsert>() {
@Override
public int compare(final BulkWriteUpsert o1, final BulkWriteUpsert o2) {
return (o1.getIndex() < o2.getIndex()) ? -1 : ((o1.getIndex() == o2.getIndex()) ? 0 : 1);
}
});
private final Set<BulkWriteError> writeErrors = new TreeSet<BulkWriteError>(new Comparator<BulkWriteError>() {
@Override
public int compare(final BulkWriteError o1, final BulkWriteError o2) {
return (o1.getIndex() < o2.getIndex()) ? -1 : ((o1.getIndex() == o2.getIndex()) ? 0 : 1);
}
});
private final List<WriteConcernError> writeConcernErrors = new ArrayList<WriteConcernError>();
public BulkWriteBatchCombiner(final ServerAddress serverAddress, final boolean ordered, final WriteConcern writeConcern) {
this.writeConcern = notNull("writeConcern", writeConcern);
this.ordered = ordered;
this.serverAddress = notNull("serverAddress", serverAddress);
}
public void addResult(final BulkWriteResult result, final IndexMap indexMap) {
insertedCount += result.getInsertedCount();
matchedCount += result.getMatchedCount();
deletedCount += result.getDeletedCount();
modifiedCount += result.getModifiedCount();
mergeUpserts(result.getUpserts(), indexMap);
}
public void addErrorResult(final MongoBulkWriteException exception, final IndexMap indexMap) {
addResult(exception.getWriteResult(), indexMap);
mergeWriteErrors(exception.getWriteErrors(), indexMap);
mergeWriteConcernError(exception.getWriteConcernError());
}
public void addWriteErrorResult(final BulkWriteError writeError, final IndexMap indexMap) {
notNull("writeError", writeError);
mergeWriteErrors(asList(writeError), indexMap);
}
public void addWriteConcernErrorResult(final WriteConcernError writeConcernError) {
notNull("writeConcernError", writeConcernError);
mergeWriteConcernError(writeConcernError);
}
public void addErrorResult(final List<BulkWriteError> writeErrors,
final WriteConcernError writeConcernError, final IndexMap indexMap) {
mergeWriteErrors(writeErrors, indexMap);
mergeWriteConcernError(writeConcernError);
}
public BulkWriteResult getResult() {
throwOnError();
return createResult();
}
public boolean shouldStopSendingMoreBatches() {
return ordered && hasWriteErrors();
}
public boolean hasErrors() {
return hasWriteErrors() || hasWriteConcernErrors();
}
public MongoBulkWriteException getError() {
return hasErrors() ? new MongoBulkWriteException(createResult(),
new ArrayList<BulkWriteError>(writeErrors),
writeConcernErrors.isEmpty() ? null
: writeConcernErrors.get(writeConcernErrors.size() - 1),
serverAddress) : null;
}
private void mergeWriteConcernError(final WriteConcernError writeConcernError) {
if (writeConcernError != null) {
if (writeConcernErrors.isEmpty()) {
writeConcernErrors.add(writeConcernError);
} else if (!writeConcernError.equals(writeConcernErrors.get(writeConcernErrors.size() - 1))) {
writeConcernErrors.add(writeConcernError);
}
}
}
private void mergeWriteErrors(final List<BulkWriteError> newWriteErrors, final IndexMap indexMap) {
for (BulkWriteError cur : newWriteErrors) {
this.writeErrors.add(new BulkWriteError(cur.getCode(), cur.getMessage(), cur.getDetails(), indexMap.map(cur.getIndex())
));
}
}
private void mergeUpserts(final List<BulkWriteUpsert> upserts, final IndexMap indexMap) {
for (BulkWriteUpsert bulkWriteUpsert : upserts) {
writeUpserts.add(new BulkWriteUpsert(indexMap.map(bulkWriteUpsert.getIndex()), bulkWriteUpsert.getId()));
}
}
private void throwOnError() {
if (hasErrors()) {
throw getError();
}
}
private BulkWriteResult createResult() {
return writeConcern.isAcknowledged()
? BulkWriteResult.acknowledged(insertedCount, matchedCount, deletedCount, modifiedCount,
new ArrayList<BulkWriteUpsert>(writeUpserts))
: BulkWriteResult.unacknowledged();
}
private boolean hasWriteErrors() {
return !writeErrors.isEmpty();
}
private boolean hasWriteConcernErrors() {
return !writeConcernErrors.isEmpty();
}
}