55:mod:`collections` module in the Python standard library can be used as a Zarr
66array store, as long as it accepts string (str) keys and bytes values.
77
8+ In addition to the :class:`MutableMapping` interface, store classes may also implement
9+ optional methods `listdir` (list members of a "directory") and `rmdir` (remove all
10+ members of a "directory"). These methods should be implemented if the store class is
11+ aware of the hierarchical organisation of resources within the store and can provide
12+ efficient implementations. If these methods are not available, Zarr will fall back to
13+ slower implementations that work via the :class:`MutableMapping` interface. Store
14+ classes may also optionally implement a `rename` method (rename all members under a given
15+ path) and a `getsize` method (return the size in bytes of a given value).
16+
817"""
918from __future__ import absolute_import , print_function , division
1019from collections import MutableMapping , OrderedDict
@@ -80,7 +89,9 @@ def _rmdir_from_keys(store, path=None):
8089
8190
8291def rmdir (store , path = None ):
83- """Remove all items under the given path."""
92+ """Remove all items under the given path. If `store` provides a `rmdir` method,
93+ this will be called, otherwise will fall back to implementation via the
94+ `MutableMapping` interface."""
8495 path = normalize_storage_path (path )
8596 if hasattr (store , 'rmdir' ):
8697 # pass through
@@ -101,7 +112,9 @@ def _rename_from_keys(store, src_path, dst_path):
101112
102113
103114def rename (store , src_path , dst_path ):
104- """Rename all items under the given path."""
115+ """Rename all items under the given path. If `store` provides a `rename` method,
116+ this will be called, otherwise will fall back to implementation via the
117+ `MutableMapping` interface."""
105118 src_path = normalize_storage_path (src_path )
106119 dst_path = normalize_storage_path (dst_path )
107120 if hasattr (store , 'rename' ):
@@ -125,7 +138,9 @@ def _listdir_from_keys(store, path=None):
125138
126139
127140def listdir (store , path = None ):
128- """Obtain a directory listing for the given path."""
141+ """Obtain a directory listing for the given path. If `store` provides a `listdir`
142+ method, this will be called, otherwise will fall back to implementation via the
143+ `MutableMapping` interface."""
129144 path = normalize_storage_path (path )
130145 if hasattr (store , 'listdir' ):
131146 # pass through
@@ -136,7 +151,8 @@ def listdir(store, path=None):
136151
137152
138153def getsize (store , path = None ):
139- """Compute size of stored items for a given path."""
154+ """Compute size of stored items for a given path. If `store` provides a `getsize`
155+ method, this will be called, otherwise will return -1."""
140156 path = normalize_storage_path (path )
141157 if hasattr (store , 'getsize' ):
142158 # pass through
@@ -868,6 +884,7 @@ def atexit_rmtree(path,
868884 rmtree (path )
869885
870886
887+ # noinspection PyShadowingNames
871888def atexit_rmglob (path ,
872889 glob = glob .glob ,
873890 isdir = os .path .isdir ,
@@ -1690,6 +1707,35 @@ def __len__(self):
16901707
16911708
16921709class LRUStoreCache (MutableMapping ):
1710+ """Storage class that implements a least-recently-used (LRU) cache layer over
1711+ some other store. Intended primarily for use with stores that can be slow to
1712+ access, e.g., remote stores that require network communication to store and
1713+ retrieve data.
1714+
1715+ Parameters
1716+ ----------
1717+ store : MutableMapping
1718+ The store containing the actual data to be cached.
1719+ max_size : int
1720+ The maximum size that the cache may grow to, in number of bytes. Provide `None`
1721+ if you would like the cache to have unlimited size.
1722+
1723+ Examples
1724+ --------
1725+ The example below wraps an S3 store with an LRU cache::
1726+
1727+ >>> import s3fs
1728+ >>> import zarr
1729+ >>> s3 = s3fs.S3FileSystem(anon=True, client_kwargs=dict(region_name='eu-west-2'))
1730+ >>> store = s3fs.S3Map(root='zarr-demo/store', s3=s3, check=False)
1731+ >>> cache = zarr.LRUStoreCache(store, max_size=2**28)
1732+ >>> root = zarr.group(store=cache)
1733+ >>> z = root['foo/bar/baz']
1734+ >>> from timeit import timeit
1735+ >>> timeit('print(z.tostring())', number=1) # first time is relatively slow
1736+ >>> timeit('print(z.tostring())', number=1) # second time is fast, uses cache
1737+
1738+ """
16931739
16941740 def __init__ (self , store , max_size ):
16951741 self ._store = store
@@ -1771,10 +1817,12 @@ def _cache_value(self, key, value):
17711817 self ._current_size += value_size
17721818
17731819 def clear_values (self ):
1820+ """Clear the values cache."""
17741821 with self ._mutex :
17751822 self ._values_cache .clear ()
17761823
17771824 def clear_keys (self ):
1825+ """Clear the keys cache."""
17781826 with self ._mutex :
17791827 self ._clear_keys ()
17801828
0 commit comments