|
15 | 15 | from zarr.errors import err_path_not_found, CopyError
|
16 | 16 | from zarr.util import normalize_storage_path, TreeViewer, buffer_size
|
17 | 17 | from zarr.compat import PY2, text_type
|
| 18 | +from zarr.meta import ensure_str, json_dumps |
18 | 19 |
|
19 | 20 |
|
20 | 21 | # noinspection PyShadowingBuiltins
|
21 |
| -def open(store, mode='a', **kwargs): |
| 22 | +def open(store=None, mode='a', **kwargs): |
22 | 23 | """Convenience function to open a group or array using file-mode-like semantics.
|
23 | 24 |
|
24 | 25 | Parameters
|
25 | 26 | ----------
|
26 |
| - store : MutableMapping or string |
| 27 | + store : MutableMapping or string, optional |
27 | 28 | Store or path to directory in file system or name of zip file.
|
28 | 29 | mode : {'r', 'r+', 'a', 'w', 'w-'}, optional
|
29 | 30 | Persistence mode: 'r' means read only (must exist); 'r+' means
|
30 | 31 | read/write (must exist); 'a' means read/write (create if doesn't
|
31 | 32 | exist); 'w' means create (overwrite if exists); 'w-' means create
|
32 | 33 | (fail if exists).
|
33 | 34 | **kwargs
|
34 |
| - Additional parameters are passed through to :func:`zarr.open_array` or |
35 |
| - :func:`zarr.open_group`. |
| 35 | + Additional parameters are passed through to :func:`zarr.creation.open_array` or |
| 36 | + :func:`zarr.hierarchy.open_group`. |
| 37 | +
|
| 38 | + Returns |
| 39 | + ------- |
| 40 | + z : :class:`zarr.core.Array` or :class:`zarr.hierarchy.Group` |
| 41 | + Array or group, depending on what exists in the given store. |
36 | 42 |
|
37 | 43 | See Also
|
38 | 44 | --------
|
39 |
| - zarr.open_array, zarr.open_group |
| 45 | + zarr.creation.open_array, zarr.hierarchy.open_group |
40 | 46 |
|
41 | 47 | Examples
|
42 | 48 | --------
|
@@ -68,7 +74,8 @@ def open(store, mode='a', **kwargs):
|
68 | 74 |
|
69 | 75 | path = kwargs.get('path', None)
|
70 | 76 | # handle polymorphic store arg
|
71 |
| - store = normalize_store_arg(store, clobber=(mode == 'w')) |
| 77 | + clobber = mode == 'w' |
| 78 | + store = normalize_store_arg(store, clobber=clobber) |
72 | 79 | path = normalize_storage_path(path)
|
73 | 80 |
|
74 | 81 | if mode in {'w', 'w-', 'x'}:
|
@@ -1069,3 +1076,110 @@ def copy_all(source, dest, shallow=False, without_attrs=False, log=None,
|
1069 | 1076 | _log_copy_summary(log, dry_run, n_copied, n_skipped, n_bytes_copied)
|
1070 | 1077 |
|
1071 | 1078 | return n_copied, n_skipped, n_bytes_copied
|
| 1079 | + |
| 1080 | + |
| 1081 | +def consolidate_metadata(store, metadata_key='.zmetadata'): |
| 1082 | + """ |
| 1083 | + Consolidate all metadata for groups and arrays within the given store |
| 1084 | + into a single resource and put it under the given key. |
| 1085 | +
|
| 1086 | + This produces a single object in the backend store, containing all the |
| 1087 | + metadata read from all the zarr-related keys that can be found. After |
| 1088 | + metadata have been consolidated, use :func:`open_consolidated` to open |
| 1089 | + the root group in optimised, read-only mode, using the consolidated |
| 1090 | + metadata to reduce the number of read operations on the backend store. |
| 1091 | +
|
| 1092 | + Note, that if the metadata in the store is changed after this |
| 1093 | + consolidation, then the metadata read by :func:`open_consolidated` |
| 1094 | + would be incorrect unless this function is called again. |
| 1095 | +
|
| 1096 | + .. note:: This is an experimental feature. |
| 1097 | +
|
| 1098 | + Parameters |
| 1099 | + ---------- |
| 1100 | + store : MutableMapping or string |
| 1101 | + Store or path to directory in file system or name of zip file. |
| 1102 | + metadata_key : str |
| 1103 | + Key to put the consolidated metadata under. |
| 1104 | +
|
| 1105 | + Returns |
| 1106 | + ------- |
| 1107 | + g : :class:`zarr.hierarchy.Group` |
| 1108 | + Group instance, opened with the new consolidated metadata. |
| 1109 | +
|
| 1110 | + See Also |
| 1111 | + -------- |
| 1112 | + open_consolidated |
| 1113 | +
|
| 1114 | + """ |
| 1115 | + import json |
| 1116 | + |
| 1117 | + store = normalize_store_arg(store) |
| 1118 | + |
| 1119 | + def is_zarr_key(key): |
| 1120 | + return (key.endswith('.zarray') or key.endswith('.zgroup') or |
| 1121 | + key.endswith('.zattrs')) |
| 1122 | + |
| 1123 | + out = { |
| 1124 | + 'zarr_consolidated_format': 1, |
| 1125 | + 'metadata': { |
| 1126 | + key: json.loads(ensure_str(store[key])) |
| 1127 | + for key in store if is_zarr_key(key) |
| 1128 | + } |
| 1129 | + } |
| 1130 | + store[metadata_key] = json_dumps(out).encode() |
| 1131 | + return open_consolidated(store, metadata_key=metadata_key) |
| 1132 | + |
| 1133 | + |
| 1134 | +def open_consolidated(store, metadata_key='.zmetadata', mode='r+'): |
| 1135 | + """Open group using metadata previously consolidated into a single key. |
| 1136 | +
|
| 1137 | + This is an optimised method for opening a Zarr group, where instead of |
| 1138 | + traversing the group/array hierarchy by accessing the metadata keys at |
| 1139 | + each level, a single key contains all of the metadata for everything. |
| 1140 | + For remote data sources where the overhead of accessing a key is large |
| 1141 | + compared to the time to read data. |
| 1142 | +
|
| 1143 | + The group accessed must have already had its metadata consolidated into a |
| 1144 | + single key using the function :func:`consolidate_metadata`. |
| 1145 | +
|
| 1146 | + This optimised method only works in modes which do not change the |
| 1147 | + metadata, although the data may still be written/updated. |
| 1148 | +
|
| 1149 | + Parameters |
| 1150 | + ---------- |
| 1151 | + store : MutableMapping or string |
| 1152 | + Store or path to directory in file system or name of zip file. |
| 1153 | + metadata_key : str |
| 1154 | + Key to read the consolidated metadata from. The default (.zmetadata) |
| 1155 | + corresponds to the default used by :func:`consolidate_metadata`. |
| 1156 | + mode : {'r', 'r+'}, optional |
| 1157 | + Persistence mode: 'r' means read only (must exist); 'r+' means |
| 1158 | + read/write (must exist) although only writes to data are allowed, |
| 1159 | + changes to metadata including creation of new arrays or group |
| 1160 | + are not allowed. |
| 1161 | +
|
| 1162 | + Returns |
| 1163 | + ------- |
| 1164 | + g : :class:`zarr.hierarchy.Group` |
| 1165 | + Group instance, opened with the consolidated metadata. |
| 1166 | +
|
| 1167 | + See Also |
| 1168 | + -------- |
| 1169 | + consolidate_metadata |
| 1170 | +
|
| 1171 | + """ |
| 1172 | + |
| 1173 | + from .storage import ConsolidatedMetadataStore |
| 1174 | + |
| 1175 | + # normalize parameters |
| 1176 | + store = normalize_store_arg(store) |
| 1177 | + if mode not in {'r', 'r+'}: |
| 1178 | + raise ValueError("invalid mode, expected either 'r' or 'r+'; found {!r}" |
| 1179 | + .format(mode)) |
| 1180 | + |
| 1181 | + # setup metadata sotre |
| 1182 | + meta_store = ConsolidatedMetadataStore(store, metadata_key=metadata_key) |
| 1183 | + |
| 1184 | + # pass through |
| 1185 | + return open(store=meta_store, chunk_store=store, mode=mode) |
0 commit comments