Skip to content

Commit 5fc8385

Browse files
committed
add cache_attrs to API
1 parent 18f0dc1 commit 5fc8385

File tree

3 files changed

+59
-18
lines changed

3 files changed

+59
-18
lines changed

zarr/core.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class Array(object):
4343
synchronizer : object, optional
4444
Array synchronizer.
4545
cache_metadata : bool, optional
46-
If True, array configuration metadata will be cached for the
46+
If True (default), array configuration metadata will be cached for the
4747
lifetime of the object. If False, array metadata will be reloaded
4848
prior to all data access and modification operations (may incur
4949
overhead depending on storage and data access pattern).

zarr/creation.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
def create(shape, chunks=True, dtype=None, compressor='default',
1717
fill_value=0, order='C', store=None, synchronizer=None,
1818
overwrite=False, path=None, chunk_store=None, filters=None,
19-
cache_metadata=True, read_only=False, object_codec=None,
20-
**kwargs):
19+
cache_metadata=True, cache_attrs=True, read_only=False,
20+
object_codec=None, **kwargs):
2121
"""Create an array.
2222
2323
Parameters
@@ -54,6 +54,10 @@ def create(shape, chunks=True, dtype=None, compressor='default',
5454
lifetime of the object. If False, array metadata will be reloaded
5555
prior to all data access and modification operations (may incur
5656
overhead depending on storage and data access pattern).
57+
cache_attrs : bool, optional
58+
If True (default), user attributes will be cached for attribute read
59+
operations. If False, user attributes are reloaded from the store prior
60+
to all attribute read operations.
5761
read_only : bool, optional
5862
True if array should be protected against modification.
5963
object_codec : Codec, optional
@@ -115,7 +119,7 @@ def create(shape, chunks=True, dtype=None, compressor='default',
115119

116120
# instantiate array
117121
z = Array(store, path=path, chunk_store=chunk_store, synchronizer=synchronizer,
118-
cache_metadata=cache_metadata, read_only=read_only)
122+
cache_metadata=cache_metadata, cache_attrs=cache_attrs, read_only=read_only)
119123

120124
return z
121125

@@ -342,8 +346,9 @@ def array(data, **kwargs):
342346

343347

344348
def open_array(store, mode='a', shape=None, chunks=True, dtype=None, compressor='default',
345-
fill_value=0, order='C', synchronizer=None, filters=None, cache_metadata=True,
346-
path=None, object_codec=None, **kwargs):
349+
fill_value=0, order='C', synchronizer=None, filters=None,
350+
cache_metadata=True, cache_attrs=True, path=None, object_codec=None,
351+
**kwargs):
347352
"""Open an array using file-mode-like semantics.
348353
349354
Parameters
@@ -377,6 +382,10 @@ def open_array(store, mode='a', shape=None, chunks=True, dtype=None, compressor=
377382
lifetime of the object. If False, array metadata will be reloaded
378383
prior to all data access and modification operations (may incur
379384
overhead depending on storage and data access pattern).
385+
cache_attrs : bool, optional
386+
If True (default), user attributes will be cached for attribute read
387+
operations. If False, user attributes are reloaded from the store prior
388+
to all attribute read operations.
380389
path : string, optional
381390
Array path within store.
382391
object_codec : Codec, optional
@@ -465,7 +474,7 @@ def open_array(store, mode='a', shape=None, chunks=True, dtype=None, compressor=
465474

466475
# instantiate array
467476
z = Array(store, read_only=read_only, synchronizer=synchronizer,
468-
cache_metadata=cache_metadata, path=path)
477+
cache_metadata=cache_metadata, cache_attrs=cache_attrs, path=path)
469478

470479
return z
471480

zarr/hierarchy.py

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ class Group(MutableMapping):
3535
chunk_store : MutableMapping, optional
3636
Separate storage for chunks. If not provided, `store` will be used
3737
for storage of both chunks and metadata.
38+
cache_attrs : bool, optional
39+
If True (default), user attributes will be cached for attribute read
40+
operations. If False, user attributes are reloaded from the store prior
41+
to all attribute read operations.
3842
synchronizer : object, optional
3943
Array synchronizer.
4044
@@ -86,7 +90,7 @@ class Group(MutableMapping):
8690
"""
8791

8892
def __init__(self, store, path=None, read_only=False, chunk_store=None,
89-
synchronizer=None):
93+
cache_attrs=True, synchronizer=None):
9094

9195
self._store = store
9296
self._chunk_store = chunk_store
@@ -115,7 +119,7 @@ def __init__(self, store, path=None, read_only=False, chunk_store=None,
115119
# setup attributes
116120
akey = self._key_prefix + attrs_key
117121
self._attrs = Attributes(store, key=akey, read_only=read_only,
118-
synchronizer=synchronizer)
122+
cache=cache_attrs, synchronizer=synchronizer)
119123

120124
# setup info
121125
self._info = InfoReporter(self)
@@ -320,10 +324,12 @@ def __getitem__(self, item):
320324
path = self._item_path(item)
321325
if contains_array(self._store, path):
322326
return Array(self._store, read_only=self._read_only, path=path,
323-
chunk_store=self._chunk_store, synchronizer=self._synchronizer)
327+
chunk_store=self._chunk_store,
328+
synchronizer=self._synchronizer, cache_attrs=self.attrs.cache)
324329
elif contains_group(self._store, path):
325330
return Group(self._store, read_only=self._read_only, path=path,
326-
chunk_store=self._chunk_store, synchronizer=self._synchronizer)
331+
chunk_store=self._chunk_store, cache_attrs=self.attrs.cache,
332+
synchronizer=self._synchronizer)
327333
else:
328334
raise KeyError(item)
329335

@@ -403,6 +409,7 @@ def groups(self):
403409
if contains_group(self._store, path):
404410
yield key, Group(self._store, path=path, read_only=self._read_only,
405411
chunk_store=self._chunk_store,
412+
cache_attrs=self.attrs.cache,
406413
synchronizer=self._synchronizer)
407414

408415
def array_keys(self):
@@ -447,6 +454,7 @@ def arrays(self):
447454
if contains_array(self._store, path):
448455
yield key, Array(self._store, path=path, read_only=self._read_only,
449456
chunk_store=self._chunk_store,
457+
cache_attrs=self.attrs.cache,
450458
synchronizer=self._synchronizer)
451459

452460
def visitvalues(self, func):
@@ -649,7 +657,8 @@ def _create_group_nosync(self, name, overwrite=False):
649657
overwrite=overwrite)
650658

651659
return Group(self._store, path=path, read_only=self._read_only,
652-
chunk_store=self._chunk_store, synchronizer=self._synchronizer)
660+
chunk_store=self._chunk_store, cache_attrs=self.attrs.cache,
661+
synchronizer=self._synchronizer)
653662

654663
def create_groups(self, *names, **kwargs):
655664
"""Convenience method to create multiple groups in a single call."""
@@ -692,7 +701,8 @@ def _require_group_nosync(self, name, overwrite=False):
692701
overwrite=overwrite)
693702

694703
return Group(self._store, path=path, read_only=self._read_only,
695-
chunk_store=self._chunk_store, synchronizer=self._synchronizer)
704+
chunk_store=self._chunk_store, cache_attrs=self.attrs.cache,
705+
synchronizer=self._synchronizer)
696706

697707
def require_groups(self, *names):
698708
"""Convenience method to require multiple groups in a single call."""
@@ -760,6 +770,7 @@ def _create_dataset_nosync(self, name, data=None, **kwargs):
760770

761771
# determine synchronizer
762772
kwargs.setdefault('synchronizer', self._synchronizer)
773+
kwargs.setdefault('cache_attrs', self.attrs.cache)
763774

764775
# create array
765776
if data is None:
@@ -804,9 +815,10 @@ def _require_dataset_nosync(self, name, shape, dtype=None, exact=False,
804815

805816
synchronizer = kwargs.get('synchronizer', self._synchronizer)
806817
cache_metadata = kwargs.get('cache_metadata', True)
818+
cache_attrs = kwargs.get('cache_attrs', self.attrs.cache)
807819
a = Array(self._store, path=path, read_only=self._read_only,
808820
chunk_store=self._chunk_store, synchronizer=synchronizer,
809-
cache_metadata=cache_metadata)
821+
cache_metadata=cache_metadata, cache_attrs=cache_attrs)
810822
shape = normalize_shape(shape)
811823
if shape != a.shape:
812824
raise TypeError('shape do not match existing array; expected {}, got {}'
@@ -834,6 +846,7 @@ def create(self, name, **kwargs):
834846
def _create_nosync(self, name, **kwargs):
835847
path = self._item_path(name)
836848
kwargs.setdefault('synchronizer', self._synchronizer)
849+
kwargs.setdefault('cache_attrs', self.attrs.cache)
837850
return create(store=self._store, path=path, chunk_store=self._chunk_store,
838851
**kwargs)
839852

@@ -845,6 +858,7 @@ def empty(self, name, **kwargs):
845858
def _empty_nosync(self, name, **kwargs):
846859
path = self._item_path(name)
847860
kwargs.setdefault('synchronizer', self._synchronizer)
861+
kwargs.setdefault('cache_attrs', self.attrs.cache)
848862
return empty(store=self._store, path=path, chunk_store=self._chunk_store,
849863
**kwargs)
850864

@@ -856,6 +870,7 @@ def zeros(self, name, **kwargs):
856870
def _zeros_nosync(self, name, **kwargs):
857871
path = self._item_path(name)
858872
kwargs.setdefault('synchronizer', self._synchronizer)
873+
kwargs.setdefault('cache_attrs', self.attrs.cache)
859874
return zeros(store=self._store, path=path, chunk_store=self._chunk_store,
860875
**kwargs)
861876

@@ -867,6 +882,7 @@ def ones(self, name, **kwargs):
867882
def _ones_nosync(self, name, **kwargs):
868883
path = self._item_path(name)
869884
kwargs.setdefault('synchronizer', self._synchronizer)
885+
kwargs.setdefault('cache_attrs', self.attrs.cache)
870886
return ones(store=self._store, path=path, chunk_store=self._chunk_store, **kwargs)
871887

872888
def full(self, name, fill_value, **kwargs):
@@ -877,6 +893,7 @@ def full(self, name, fill_value, **kwargs):
877893
def _full_nosync(self, name, fill_value, **kwargs):
878894
path = self._item_path(name)
879895
kwargs.setdefault('synchronizer', self._synchronizer)
896+
kwargs.setdefault('cache_attrs', self.attrs.cache)
880897
return full(store=self._store, path=path, chunk_store=self._chunk_store,
881898
fill_value=fill_value, **kwargs)
882899

@@ -888,6 +905,7 @@ def array(self, name, data, **kwargs):
888905
def _array_nosync(self, name, data, **kwargs):
889906
path = self._item_path(name)
890907
kwargs.setdefault('synchronizer', self._synchronizer)
908+
kwargs.setdefault('cache_attrs', self.attrs.cache)
891909
return array(data, store=self._store, path=path, chunk_store=self._chunk_store,
892910
**kwargs)
893911

@@ -899,6 +917,7 @@ def empty_like(self, name, data, **kwargs):
899917
def _empty_like_nosync(self, name, data, **kwargs):
900918
path = self._item_path(name)
901919
kwargs.setdefault('synchronizer', self._synchronizer)
920+
kwargs.setdefault('cache_attrs', self.attrs.cache)
902921
return empty_like(data, store=self._store, path=path,
903922
chunk_store=self._chunk_store, **kwargs)
904923

@@ -910,6 +929,7 @@ def zeros_like(self, name, data, **kwargs):
910929
def _zeros_like_nosync(self, name, data, **kwargs):
911930
path = self._item_path(name)
912931
kwargs.setdefault('synchronizer', self._synchronizer)
932+
kwargs.setdefault('cache_attrs', self.attrs.cache)
913933
return zeros_like(data, store=self._store, path=path,
914934
chunk_store=self._chunk_store, **kwargs)
915935

@@ -921,6 +941,7 @@ def ones_like(self, name, data, **kwargs):
921941
def _ones_like_nosync(self, name, data, **kwargs):
922942
path = self._item_path(name)
923943
kwargs.setdefault('synchronizer', self._synchronizer)
944+
kwargs.setdefault('cache_attrs', self.attrs.cache)
924945
return ones_like(data, store=self._store, path=path,
925946
chunk_store=self._chunk_store, **kwargs)
926947

@@ -932,6 +953,7 @@ def full_like(self, name, data, **kwargs):
932953
def _full_like_nosync(self, name, data, **kwargs):
933954
path = self._item_path(name)
934955
kwargs.setdefault('synchronizer', self._synchronizer)
956+
kwargs.setdefault('cache_attrs', self.attrs.cache)
935957
return full_like(data, store=self._store, path=path,
936958
chunk_store=self._chunk_store, **kwargs)
937959

@@ -971,7 +993,8 @@ def _normalize_store_arg(store, clobber=False):
971993
return normalize_store_arg(store, clobber=clobber, default=DictStore)
972994

973995

974-
def group(store=None, overwrite=False, chunk_store=None, synchronizer=None, path=None):
996+
def group(store=None, overwrite=False, chunk_store=None,
997+
cache_attrs=True, synchronizer=None, path=None):
975998
"""Create a group.
976999
9771000
Parameters
@@ -984,6 +1007,10 @@ def group(store=None, overwrite=False, chunk_store=None, synchronizer=None, path
9841007
chunk_store : MutableMapping, optional
9851008
Separate storage for chunks. If not provided, `store` will be used
9861009
for storage of both chunks and metadata.
1010+
cache_attrs : bool, optional
1011+
If True (default), user attributes will be cached for attribute read
1012+
operations. If False, user attributes are reloaded from the store prior
1013+
to all attribute read operations.
9871014
synchronizer : object, optional
9881015
Array synchronizer.
9891016
path : string, optional
@@ -1021,10 +1048,10 @@ def group(store=None, overwrite=False, chunk_store=None, synchronizer=None, path
10211048
path=path)
10221049

10231050
return Group(store, read_only=False, chunk_store=chunk_store,
1024-
synchronizer=synchronizer, path=path)
1051+
cache_attrs=cache_attrs, synchronizer=synchronizer, path=path)
10251052

10261053

1027-
def open_group(store, mode='a', synchronizer=None, path=None):
1054+
def open_group(store, mode='a', cache_attrs=True, synchronizer=None, path=None):
10281055
"""Open a group using file-mode-like semantics.
10291056
10301057
Parameters
@@ -1036,6 +1063,10 @@ def open_group(store, mode='a', synchronizer=None, path=None):
10361063
read/write (must exist); 'a' means read/write (create if doesn't
10371064
exist); 'w' means create (overwrite if exists); 'w-' means create
10381065
(fail if exists).
1066+
cache_attrs : bool, optional
1067+
If True (default), user attributes will be cached for attribute read
1068+
operations. If False, user attributes are reloaded from the store prior
1069+
to all attribute read operations.
10391070
synchronizer : object, optional
10401071
Array synchronizer.
10411072
path : string, optional
@@ -1093,4 +1124,5 @@ def open_group(store, mode='a', synchronizer=None, path=None):
10931124
# determine read only status
10941125
read_only = mode == 'r'
10951126

1096-
return Group(store, read_only=read_only, synchronizer=synchronizer, path=path)
1127+
return Group(store, read_only=read_only, cache_attrs=cache_attrs,
1128+
synchronizer=synchronizer, path=path)

0 commit comments

Comments
 (0)