Skip to content

Commit 52aa43b

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 52aa43b

File tree

1 file changed

+36
-8
lines changed

1 file changed

+36
-8
lines changed

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

+36-8
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,16 @@
1818

1919
import static java.util.Objects.requireNonNull;
2020

21+
import static com.google.common.base.Throwables.getStackTraceAsString;
2122
import static com.google.common.base.Throwables.propagate;
2223

2324
import java.io.BufferedReader;
2425
import java.io.IOException;
2526
import java.io.InputStreamReader;
2627
import java.util.ArrayList;
28+
import java.util.HashMap;
2729
import java.util.List;
30+
import java.util.Map;
2831
import java.util.Objects;
2932
import java.util.Optional;
3033
import java.util.stream.Collectors;
@@ -151,34 +154,59 @@ public BulkDeleteResult bulkDelete(@NotNull @PathParam("account") String account
151154
}
152155

153156
BulkDeleteResult result = new BulkDeleteResult();
157+
Map<String, List<String>> removeBlobsMap = new HashMap<>();
158+
List<String> deleteContainers = new ArrayList<>();
154159
for (String objectContainer : objects) {
155160
try {
156161
if (objectContainer.startsWith("/")) {
157162
objectContainer = objectContainer.substring(1);
158163
}
159164
int separatorIndex = objectContainer.indexOf('/');
160165
if (separatorIndex < 0) {
161-
blobStore.deleteContainer(objectContainer.substring(1));
162-
result.numberDeleted += 1;
166+
deleteContainers.add(objectContainer.substring(1));
163167
continue;
164168
}
165169
String container = objectContainer.substring(0, separatorIndex);
166170
String object = objectContainer.substring(separatorIndex + 1);
167171

168-
if (!blobStore.blobExists(container, object)) {
169-
result.numberNotFound += 1;
170-
} else {
171-
blobStore.removeBlob(container, object);
172-
result.numberDeleted += 1;
172+
if (!removeBlobsMap.containsKey(container)) {
173+
removeBlobsMap.put(container, new ArrayList<>());
173174
}
175+
removeBlobsMap.get(container).add(object);
174176
} catch (ContainerNotFoundException e) {
175177
result.numberNotFound += 1;
176178
} catch (Exception e) {
177-
e.printStackTrace();
179+
logger.error(e.toString());
180+
logger.debug(getStackTraceAsString(e));
178181
result.errors.add(objectContainer);
179182
}
180183
}
181184

185+
removeBlobsMap.forEach((container, blobList) -> {
186+
try {
187+
blobStore.removeBlobs(container, blobList);
188+
result.numberDeleted += blobList.size();
189+
} catch (ContainerNotFoundException e) {
190+
result.numberNotFound += blobList.size();
191+
} catch (Exception e) {
192+
logger.error(e.toString());
193+
logger.debug(getStackTraceAsString(e));
194+
blobList.forEach(blob -> result.errors.add(container + "/" + blob));
195+
}
196+
});
197+
deleteContainers.forEach(container -> {
198+
try {
199+
blobStore.deleteContainer(container);
200+
result.numberDeleted += 1;
201+
} catch (ContainerNotFoundException e) {
202+
result.numberNotFound += 1;
203+
} catch (Exception e) {
204+
logger.error(e.toString());
205+
logger.debug(getStackTraceAsString(e));
206+
result.errors.add(container);
207+
}
208+
});
209+
182210
if (result.errors.isEmpty()) {
183211
result.responseStatus = Response.Status.OK.toString();
184212
return result;

0 commit comments

Comments
 (0)