@@ -65,6 +65,13 @@ def _get_snapshot(self, snapshot_id: int | None = None) -> Snapshot:
6565 else :
6666 raise ValueError ("Cannot get a snapshot as the table does not have any." )
6767
68+ def _get_snapshots_by_id (self ) -> dict [int , Snapshot ]:
69+ """Index the snapshots by ID, for methods that look up many of them.
70+
71+ snapshot_by_id is a linear scan, so calling it once per row is quadratic.
72+ """
73+ return {snapshot .snapshot_id : snapshot for snapshot in self .tbl .metadata .snapshots }
74+
6875 def snapshots (self ) -> pa .Table :
6976 import pyarrow as pa
7077
@@ -310,8 +317,7 @@ def partitions(
310317 )
311318
312319 partitions_map : dict [tuple [str , Any ], Any ] = {}
313- # snapshot_by_id is a linear scan, and there is one lookup per manifest entry
314- snapshots_by_id = {snapshot .snapshot_id : snapshot for snapshot in self .tbl .metadata .snapshots }
320+ snapshots_by_id = self ._get_snapshots_by_id ()
315321
316322 for entry in itertools .chain .from_iterable (scan ._plan_manifest_entries ()):
317323 partition = entry .data_file .partition
@@ -534,8 +540,7 @@ def history(self) -> pa.Table:
534540
535541 history = []
536542 metadata = self .tbl .metadata
537- # snapshot_by_id is a linear scan, and there is one lookup per snapshot log entry
538- snapshots_by_id = {snapshot .snapshot_id : snapshot for snapshot in metadata .snapshots }
543+ snapshots_by_id = self ._get_snapshots_by_id ()
539544
540545 for snapshot_entry in metadata .snapshot_log :
541546 snapshot = snapshots_by_id .get (snapshot_entry .snapshot_id )
0 commit comments