Skip to content

Commit 11ac3d9

Browse files
committed
Implement asynchronous directory deletion in FsspecStore
- override Store.delete_dir default method, which deletes keys one by one, to support bulk deletion for fsspec implementations that support a list of paths in the fs._rm method. - This can greatly reduce the number of requests to S3, which reduces likelihood of running into throttling errors and improves delete performance. - Currently, only s3fs is supported.
1 parent 22634ea commit 11ac3d9

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

src/zarr/storage/_fsspec.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,49 @@ async def delete(self, key: str) -> None:
261261
except self.allowed_exceptions:
262262
pass
263263

264+
async def delete_dir(self, prefix: str) -> None:
265+
"""
266+
Remove all keys and prefixes in the store that begin with a given prefix.
267+
"""
268+
if not self.supports_deletes:
269+
raise NotImplementedError
270+
if not self.supports_listing:
271+
raise NotImplementedError
272+
self._check_writable()
273+
274+
if prefix and not prefix.endswith("/"):
275+
prefix += "/"
276+
277+
paths_to_delete = []
278+
async for key in self.list_prefix(prefix):
279+
paths_to_delete.append(_dereference_path(self.path, key))
280+
281+
if not paths_to_delete:
282+
return
283+
284+
try:
285+
import s3fs
286+
except ImportError:
287+
s3fs = None
288+
289+
# If s3fs is installed and our filesystem is S3FileSystem, do a bulk delete
290+
if s3fs and isinstance(self.fs, s3fs.S3FileSystem):
291+
try:
292+
await self.fs._rm(paths_to_delete)
293+
except FileNotFoundError:
294+
pass
295+
except self.allowed_exceptions:
296+
pass
297+
else:
298+
# Otherwise, delete one by one
299+
for path in paths_to_delete:
300+
try:
301+
await self.fs._rm(path)
302+
except FileNotFoundError:
303+
pass
304+
except self.allowed_exceptions:
305+
pass
306+
264307
async def exists(self, key: str) -> bool:
265308
# docstring inherited
266309
path = _dereference_path(self.path, key)

0 commit comments

Comments
 (0)