Skip to content

Commit 7c9fe56

Browse files
author
Timur Alperovich
committed
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
1 parent b2c46e6 commit 7c9fe56

File tree

1 file changed

+38
-21
lines changed

1 file changed

+38
-21
lines changed

src/main/java/com/bouncestorage/swiftproxy/v1/AccountResource.java

+38-21
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@
2424
import java.io.IOException;
2525
import java.io.InputStreamReader;
2626
import java.util.ArrayList;
27+
import java.util.HashMap;
2728
import java.util.List;
29+
import java.util.Map;
2830
import java.util.Objects;
2931
import java.util.Optional;
3032
import java.util.stream.Collectors;
@@ -151,33 +153,48 @@ public BulkDeleteResult bulkDelete(@NotNull @PathParam("account") String account
151153
}
152154

153155
BulkDeleteResult result = new BulkDeleteResult();
156+
Map<String, List<String>> removeBlobsMap = new HashMap<>();
157+
List<String> deleteContainers = new ArrayList<>();
154158
for (String objectContainer : objects) {
159+
if (objectContainer.startsWith("/")) {
160+
objectContainer = objectContainer.substring(1);
161+
}
162+
int separatorIndex = objectContainer.indexOf('/');
163+
if (separatorIndex < 0) {
164+
deleteContainers.add(objectContainer.substring(1));
165+
continue;
166+
}
167+
String container = objectContainer.substring(0, separatorIndex);
168+
String object = objectContainer.substring(separatorIndex + 1);
169+
170+
if (!removeBlobsMap.containsKey(container)) {
171+
removeBlobsMap.put(container, new ArrayList<>());
172+
}
173+
removeBlobsMap.get(container).add(object);
174+
}
175+
176+
removeBlobsMap.forEach((container, blobList) -> {
155177
try {
156-
if (objectContainer.startsWith("/")) {
157-
objectContainer = objectContainer.substring(1);
158-
}
159-
int separatorIndex = objectContainer.indexOf('/');
160-
if (separatorIndex < 0) {
161-
blobStore.deleteContainer(objectContainer.substring(1));
162-
result.numberDeleted += 1;
163-
continue;
164-
}
165-
String container = objectContainer.substring(0, separatorIndex);
166-
String object = objectContainer.substring(separatorIndex + 1);
167-
168-
if (!blobStore.blobExists(container, object)) {
169-
result.numberNotFound += 1;
170-
} else {
171-
blobStore.removeBlob(container, object);
172-
result.numberDeleted += 1;
173-
}
178+
blobStore.removeBlobs(container, blobList);
179+
result.numberDeleted += blobList.size();
180+
} catch (ContainerNotFoundException e) {
181+
result.numberNotFound += blobList.size();
182+
} catch (Exception e) {
183+
logger.debug("Failed to remove blobs: " + e.getMessage(), e);
184+
blobList.forEach(blob -> result.errors.add(container + "/" + blob));
185+
}
186+
});
187+
deleteContainers.forEach(container -> {
188+
try {
189+
blobStore.deleteContainer(container);
190+
result.numberDeleted += 1;
174191
} catch (ContainerNotFoundException e) {
175192
result.numberNotFound += 1;
176193
} catch (Exception e) {
177-
e.printStackTrace();
178-
result.errors.add(objectContainer);
194+
logger.debug("Failed to delete container " + container + ": " + e.getMessage(), e);
195+
result.errors.add(container);
179196
}
180-
}
197+
});
181198

182199
if (result.errors.isEmpty()) {
183200
result.responseStatus = Response.Status.OK.toString();

0 commit comments

Comments
 (0)