Coverage for python/lsst/daf/butler/registry/dimensions/caching.py : 100%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# This file is part of daf_butler.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (http://www.lsst.org).
6# See the COPYRIGHT file at the top-level directory of this distribution
7# for details of code ownership.
8#
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program. If not, see <http://www.gnu.org/licenses/>.
21from __future__ import annotations
23__all__ = ["CachingDimensionRecordStorage"]
25from typing import Dict, Optional
27import sqlalchemy
29from ...core import DataCoordinate, DataId, DimensionElement, DimensionRecord, NamedKeyDict, Timespan
30from ..interfaces import Database, DimensionRecordStorage, StaticTablesContext
31from ..queries import QueryBuilder
34class CachingDimensionRecordStorage(DimensionRecordStorage):
35 """A record storage implementation that adds caching to some other nested
36 storage implementation.
38 Parameters
39 ----------
40 nested : `DimensionRecordStorage`
41 The other storage to cache fetches from and to delegate all other
42 operations to.
43 """
44 def __init__(self, nested: DimensionRecordStorage):
45 self._nested = nested
46 self._cache: Dict[DataCoordinate, DimensionRecord] = {}
48 @classmethod
49 def initialize(cls, db: Database, element: DimensionElement, *,
50 context: Optional[StaticTablesContext] = None) -> DimensionRecordStorage:
51 # Docstring inherited from DimensionRecordStorage.
52 NestedClass = DimensionRecordStorage.getDefaultImplementation(element, ignoreCached=True)
53 nested = NestedClass.initialize(db, element, context=context)
54 return cls(nested)
56 @property
57 def element(self) -> DimensionElement:
58 # Docstring inherited from DimensionRecordStorage.element.
59 return self._nested.element
61 def clearCaches(self) -> None:
62 # Docstring inherited from DimensionRecordStorage.clearCaches.
63 self._cache.clear()
64 self._nested.clearCaches()
66 def join(
67 self,
68 builder: QueryBuilder, *,
69 regions: Optional[NamedKeyDict[DimensionElement, sqlalchemy.sql.ColumnElement]] = None,
70 timespans: Optional[NamedKeyDict[DimensionElement, Timespan[sqlalchemy.sql.ColumnElement]]] = None,
71 ) -> None:
72 # Docstring inherited from DimensionRecordStorage.
73 return self._nested.join(builder, regions=regions, timespans=timespans)
75 def insert(self, *records: DimensionRecord) -> None:
76 # Docstring inherited from DimensionRecordStorage.insert.
77 self._nested.insert(*records)
78 for record in records:
79 self._cache[record.dataId] = record
81 def sync(self, record: DimensionRecord) -> bool:
82 # Docstring inherited from DimensionRecordStorage.sync.
83 inserted = self._nested.sync(record)
84 if inserted:
85 self._cache[record.dataId] = record
86 return inserted
88 def fetch(self, dataId: DataId) -> Optional[DimensionRecord]:
89 # Docstring inherited from DimensionRecordStorage.fetch.
90 dataId = DataCoordinate.standardize(dataId, graph=self.element.graph)
91 record = self._cache.get(dataId)
92 if record is None:
93 record = self._nested.fetch(dataId)
94 if record is not None:
95 self._cache[dataId] = record
96 return record