-
-
Notifications
You must be signed in to change notification settings - Fork 282
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature: store learns to delete prefixes when overwriting/creating hierarchy nodes #2430
Changes from 12 commits
64ad525
8b706f2
59d7f79
075b929
b072545
8726734
858d4fb
c367483
a94e53c
9c173c1
939fb53
d7a6982
c38c2f7
fce2600
cafb46a
a1e71f1
0c14dd1
5677683
7e9ec76
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -371,6 +371,36 @@ def list_dir(self, prefix: str) -> AsyncGenerator[str, None]: | |
""" | ||
... | ||
|
||
async def delete_dir(self, prefix: str, recursive: bool = True) -> None: | ||
""" | ||
Remove all keys and prefixes in the store that begin with a given prefix. | ||
""" | ||
if not self.supports_deletes: | ||
raise NotImplementedError | ||
if not self.supports_listing: | ||
raise NotImplementedError | ||
self._check_writable() | ||
if recursive: | ||
if not prefix.endswith("/"): | ||
prefix += "/" | ||
async for key in self.list_prefix(prefix): | ||
await self.delete(key) | ||
else: | ||
async for key in self.list_dir(prefix): | ||
await self.delete(f"{prefix}/{key}") | ||
|
||
async def delete_prefix(self, prefix: str) -> None: | ||
jhamman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
""" | ||
Remove all keys in the store that begin with a given prefix. | ||
""" | ||
if not self.supports_deletes: | ||
raise NotImplementedError | ||
if not self.supports_listing: | ||
raise NotImplementedError | ||
self._check_writable() | ||
async for key in self.list_prefix(prefix): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we document what's the expected return value of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is done in the list_prefix docstring |
||
await self.delete(key) | ||
|
||
def close(self) -> None: | ||
"""Close the store.""" | ||
self._is_open = False | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would make life much easier for
Store
implementers if we declare thatprefix
will always be the path of a group or a array. Otherwise, all implementations need to deal with unnecessary edge cases likedelete_dir("path/to/array/c/0")
or worse.Icechunk is an example of a store that could very cleanly and efficiently implement the case for a group/array prefix, but it would struggle to handle other prefixes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the use case for
recursive = False
? If zarr itself doesn't have one, I'd remove the argument.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can see a use case for
delete_dir("path/to/array/c/")
(remove all chunks from an array) so I think we should allow that -- even if it makes life a little harder in icechunk.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's totally fine. Let's document the three possible prefix cases, and say that stores are allowed to do undefined behavior for other prefixes