Skip to content

Commit

Permalink
Use removeBlobs() for bulk-delete.
Browse files Browse the repository at this point in the history
We should use removeBlobs() for bulk-delete. The change deletes blobs
en-masse. Further, we no longer will perform a HEAD on every blob, as
that's fairly expensive.

Fixes #38
  • Loading branch information
Timur Alperovich committed Jun 17, 2015
1 parent b2c46e6 commit 7ff978e
Showing 1 changed file with 36 additions and 21 deletions.
57 changes: 36 additions & 21 deletions src/main/java/com/bouncestorage/swiftproxy/v1/AccountResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
Expand Down Expand Up @@ -56,7 +57,9 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;

import org.glassfish.grizzly.http.server.Request;
import org.jclouds.blobstore.BlobStore;
Expand Down Expand Up @@ -151,33 +154,45 @@ public BulkDeleteResult bulkDelete(@NotNull @PathParam("account") String account
}

BulkDeleteResult result = new BulkDeleteResult();
Multimap<String, String> removeBlobsMap = ArrayListMultimap.create();
List<String> deleteContainers = new ArrayList<>();
for (String objectContainer : objects) {
try {
if (objectContainer.startsWith("/")) {
objectContainer = objectContainer.substring(1);
}
int separatorIndex = objectContainer.indexOf('/');
if (separatorIndex < 0) {
blobStore.deleteContainer(objectContainer.substring(1));
result.numberDeleted += 1;
continue;
}
String container = objectContainer.substring(0, separatorIndex);
String object = objectContainer.substring(separatorIndex + 1);
if (objectContainer.startsWith("/")) {
objectContainer = objectContainer.substring(1);
}
int separatorIndex = objectContainer.indexOf('/');
if (separatorIndex < 0) {
deleteContainers.add(objectContainer.substring(1));
continue;
}
String container = objectContainer.substring(0, separatorIndex);
String object = objectContainer.substring(separatorIndex + 1);
removeBlobsMap.put(container, object);
}

if (!blobStore.blobExists(container, object)) {
result.numberNotFound += 1;
} else {
blobStore.removeBlob(container, object);
result.numberDeleted += 1;
}
removeBlobsMap.keySet().forEach(container -> {
Collection<String> blobs = removeBlobsMap.get(container);
try {
blobStore.removeBlobs(container, blobs);
result.numberDeleted += blobs.size();
} catch (ContainerNotFoundException e) {
result.numberNotFound += blobs.size();
} catch (Exception e) {
logger.debug("Failed to remove blobs: " + e.getMessage(), e);
blobs.forEach(blob -> result.errors.add(container + "/" + blob));
}
});
deleteContainers.forEach(container -> {
try {
blobStore.deleteContainer(container);
result.numberDeleted += 1;
} catch (ContainerNotFoundException e) {
result.numberNotFound += 1;
} catch (Exception e) {
e.printStackTrace();
result.errors.add(objectContainer);
logger.debug("Failed to delete container " + container + ": " + e.getMessage(), e);
result.errors.add(container);
}
}
});

if (result.errors.isEmpty()) {
result.responseStatus = Response.Status.OK.toString();
Expand Down

0 comments on commit 7ff978e

Please sign in to comment.