From c96cff52c6f017fe6a9e587fe9d3a2211ae5297a Mon Sep 17 00:00:00 2001 From: Timur Alperovich Date: Fri, 12 Jun 2015 17:52:37 -0700 Subject: [PATCH] Use removeBlobs() for bulk-delete. 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 --- .../swiftproxy/v1/AccountResource.java | 40 ++++++++++++++++--- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/bouncestorage/swiftproxy/v1/AccountResource.java b/src/main/java/com/bouncestorage/swiftproxy/v1/AccountResource.java index 3363179..73a5345 100644 --- a/src/main/java/com/bouncestorage/swiftproxy/v1/AccountResource.java +++ b/src/main/java/com/bouncestorage/swiftproxy/v1/AccountResource.java @@ -16,15 +16,17 @@ package com.bouncestorage.swiftproxy.v1; -import static java.util.Objects.requireNonNull; - import static com.google.common.base.Throwables.propagate; +import static java.util.Objects.requireNonNull; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; @@ -151,6 +153,8 @@ public BulkDeleteResult bulkDelete(@NotNull @PathParam("account") String account } BulkDeleteResult result = new BulkDeleteResult(); + Map> removeBlobsMap = new HashMap<>(); + List deleteContainers = new LinkedList<>(); for (String objectContainer : objects) { try { if (objectContainer.startsWith("/")) { @@ -158,18 +162,19 @@ public BulkDeleteResult bulkDelete(@NotNull @PathParam("account") String account } int separatorIndex = objectContainer.indexOf('/'); if (separatorIndex < 0) { - blobStore.deleteContainer(objectContainer.substring(1)); - result.numberDeleted += 1; + deleteContainers.add(objectContainer.substring(1)); continue; } String container = objectContainer.substring(0, separatorIndex); String object = objectContainer.substring(separatorIndex + 1); + if (!removeBlobsMap.containsKey(container)) { + removeBlobsMap.put(container, new LinkedList<>()); + } if (!blobStore.blobExists(container, object)) { result.numberNotFound += 1; } else { - blobStore.removeBlob(container, object); - result.numberDeleted += 1; + removeBlobsMap.get(container).add(object); } } catch (ContainerNotFoundException e) { result.numberNotFound += 1; @@ -179,6 +184,29 @@ public BulkDeleteResult bulkDelete(@NotNull @PathParam("account") String account } } + removeBlobsMap.forEach((container, blobList) -> { + try { + blobStore.removeBlobs(container, blobList); + result.numberDeleted += blobList.size(); + } catch (ContainerNotFoundException e) { + result.numberNotFound += blobList.size(); + } catch (Exception e) { + e.printStackTrace(); + blobList.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(container); + } + }); + if (result.errors.isEmpty()) { result.responseStatus = Response.Status.OK.toString(); return result;