Rangecache
rangecache
On-disk cache of the byte ranges read from remote objects.
The unit of reuse is what the source itself stores: a run of Blosc blocks of
an ARCO-ERA5 chunk, a GRIB message of an ARPEGE file, a page of an Open-Meteo
.om file. Whatever the shape of the requests (one flight, a fleet, many
calls in any order, several processes), a byte is downloaded once and served
from disk afterwards; only the missing sub-ranges of a request go over the
network.
Layout: root/<namespace>/<xx>/<digest>/ per object, holding one file per
cached extent (<start>-<stop>.bin), a size file once the end of the
object is known, and key.txt (the object key, for humans). Extent files are
written atomically (temporary file + rename) and never modified, so readers
never see a partial extent.
Missing ranges are fetched under flock locks on the 1 MiB windows they
cover (lock files live in the object's folder), taken in order, across
threads and processes; once the locks are held the cache is checked again. A
range read by several readers at once is therefore downloaded once, while
disjoint reads of one object (e.g. the levels of an ERA5 chunk) stay parallel.
Only immutable objects may be cached: each source says which of its keys are (e.g. ERA5 chunks once final, ARPEGE files of a published run, Open-Meteo chunks older than the stitching window).
CacheStats
dataclass
Thread-safe counters of what the cache served and stored.
Source code in packages/barograph-met/src/baro/met/rangecache.py
add(*, hit=0, stored=0)
Account for bytes served from disk and bytes written to it.
CachedStore
A :class:~baro.met.store.ByteStore whose immutable keys go through a :class:RangeCache.
cacheable(key) says which keys never change; the others (store
metadata, the growing time axis, objects still being rewritten) are always
read from inner. stats are the inner store's: they count only the
bytes that actually went over the network.
Source code in packages/barograph-met/src/baro/met/rangecache.py
get(key, start=None, stop=None)
Object bytes, or the [start, stop) range of them.
Source code in packages/barograph-met/src/baro/met/rangecache.py
RangeCache
Immutable byte-range cache rooted at root (see the module docstring).
Source code in packages/barograph-met/src/baro/met/rangecache.py
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | |
get(namespace, key, start, stop, fetch)
Bytes [start, stop) of key, fetching only the missing sub-ranges.
fetch(a, b) downloads [a, b); a shorter answer marks the end of
the object, and the result is then truncated there like a range read.
Source code in packages/barograph-met/src/baro/met/rangecache.py
get_full(namespace, key, fetch_all)
The whole object key, fetched once.
Source code in packages/barograph-met/src/baro/met/rangecache.py
lookup(namespace, key, start, stop)
Bytes [start, stop) of key if they are all on disk, else None.
For callers that deduplicate their own concurrent fetches (the
Open-Meteo page reader); they keep what they fetched with :meth:put.
Source code in packages/barograph-met/src/baro/met/rangecache.py
object_dir(namespace, key)
Folder of one object of one namespace.
put(namespace, key, start, data)
Keep data, the bytes of key from start on.
cover(extents, start, stop)
Split [start, stop) into cached pieces (with their file) and gaps (None).
Source code in packages/barograph-met/src/baro/met/rangecache.py
namespace_for(location)
Stable, filesystem-safe namespace for a store location (URL or directory).