1919)
2020from zarr .core .buffer import Buffer
2121from zarr .core .buffer .core import default_buffer_prototype
22- from zarr .storage ._utils import ConcurrencyLimiter , with_concurrency_limit
2322
2423if TYPE_CHECKING :
2524 from collections .abc import AsyncIterator , Iterable , Iterator
@@ -86,7 +85,7 @@ def _put(path: Path, value: Buffer, exclusive: bool = False) -> int:
8685 return f .write (view )
8786
8887
89- class LocalStore (Store , ConcurrencyLimiter ):
88+ class LocalStore (Store ):
9089 """
9190 Store for the local file system.
9291
@@ -96,9 +95,6 @@ class LocalStore(Store, ConcurrencyLimiter):
9695 Directory to use as root of store.
9796 read_only : bool
9897 Whether the store is read-only
99- concurrency_limit : int, optional
100- Maximum number of concurrent I/O operations. Default is 100.
101- Set to None for unlimited concurrency.
10298
10399 Attributes
104100 ----------
@@ -119,24 +115,21 @@ def __init__(
119115 root : Path | str ,
120116 * ,
121117 read_only : bool = False ,
122- concurrency_limit : int | None = 100 ,
123118 ) -> None :
124119 if isinstance (root , str ):
125120 root = Path (root )
126121 if not isinstance (root , Path ):
127122 raise TypeError (
128123 f"'root' must be a string or Path instance. Got an instance of { type (root )} instead."
129124 )
130- Store .__init__ (self , read_only = read_only )
131- ConcurrencyLimiter .__init__ (self , concurrency_limit )
125+ super ().__init__ (read_only = read_only )
132126 self .root = root
133127
134128 def with_read_only (self , read_only : bool = False ) -> Self :
135129 # docstring inherited
136130 return type (self )(
137131 root = self .root ,
138132 read_only = read_only ,
139- concurrency_limit = self .concurrency_limit ,
140133 )
141134
142135 @classmethod
@@ -199,7 +192,6 @@ def __repr__(self) -> str:
199192 def __eq__ (self , other : object ) -> bool :
200193 return isinstance (other , type (self )) and self .root == other .root
201194
202- @with_concurrency_limit
203195 async def get (
204196 self ,
205197 key : str ,
@@ -225,19 +217,8 @@ async def get_partial_values(
225217 key_ranges : Iterable [tuple [str , ByteRequest | None ]],
226218 ) -> list [Buffer | None ]:
227219 # docstring inherited
228- # We directly call the I/O functions here, wrapped with the semaphore,
229- # to avoid deadlock from calling the decorated get() method.
230-
231- async def _get_with_limit (key : str , byte_range : ByteRequest | None ) -> Buffer | None :
232- path = self .root / key
233- try :
234- async with self ._limit ():
235- return await asyncio .to_thread (_get , path , prototype , byte_range )
236- except (FileNotFoundError , IsADirectoryError , NotADirectoryError ):
237- return None
238-
239220 return await asyncio .gather (
240- * [_get_with_limit (key , byte_range ) for key , byte_range in key_ranges ]
221+ * [self . get (key , prototype , byte_range ) for key , byte_range in key_ranges ]
241222 )
242223
243224 async def set (self , key : str , value : Buffer ) -> None :
@@ -251,7 +232,6 @@ async def set_if_not_exists(self, key: str, value: Buffer) -> None:
251232 except FileExistsError :
252233 pass
253234
254- @with_concurrency_limit
255235 async def _set (self , key : str , value : Buffer , exclusive : bool = False ) -> None :
256236 if not self ._is_open :
257237 await self ._open ()
@@ -264,7 +244,6 @@ async def _set(self, key: str, value: Buffer, exclusive: bool = False) -> None:
264244 path = self .root / key
265245 await asyncio .to_thread (_put , path , value , exclusive = exclusive )
266246
267- @with_concurrency_limit
268247 async def delete (self , key : str ) -> None :
269248 """
270249 Remove a key from the store.
0 commit comments