1+ // Licensed to the Apache Software Foundation (ASF) under one
2+ // or more contributor license agreements. See the NOTICE file
3+ // distributed with this work for additional information
4+ // regarding copyright ownership. The ASF licenses this file
5+ // to you under the Apache License, Version 2.0 (the
6+ // "License"); you may not use this file except in compliance
7+ // with the License. You may obtain a copy of the License at
8+ //
9+ // http://www.apache.org/licenses/LICENSE-2.0
10+ //
11+ // Unless required by applicable law or agreed to in writing,
12+ // software distributed under the License is distributed on an
13+ // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+ // KIND, either express or implied. See the License for the
15+ // specific language governing permissions and limitations
16+ // under the License.
17+
18+ use crate :: spec:: { SnapshotRef , TableMetadataRef } ;
19+
20+ struct Ancestors {
21+ next : Option < SnapshotRef > ,
22+ get_snapshot : Box < dyn Fn ( i64 ) -> Option < SnapshotRef > + Send > ,
23+ }
24+
25+ impl Iterator for Ancestors {
26+ type Item = SnapshotRef ;
27+
28+ fn next ( & mut self ) -> Option < Self :: Item > {
29+ let snapshot = self . next . take ( ) ?;
30+ let result = snapshot. clone ( ) ;
31+ self . next = snapshot
32+ . parent_snapshot_id ( )
33+ . and_then ( |id| ( self . get_snapshot ) ( id) ) ;
34+ Some ( result)
35+ }
36+ }
37+
38+ /// Iterate starting from `snapshot` (inclusive) to the root snapshot.
39+ pub fn ancestors_of (
40+ table_metadata : & TableMetadataRef ,
41+ snapshot : i64 ,
42+ ) -> Box < dyn Iterator < Item = SnapshotRef > + Send > {
43+ if let Some ( snapshot) = table_metadata. snapshot_by_id ( snapshot) {
44+ let table_metadata = table_metadata. clone ( ) ;
45+ Box :: new ( Ancestors {
46+ next : Some ( snapshot. clone ( ) ) ,
47+ get_snapshot : Box :: new ( move |id| table_metadata. snapshot_by_id ( id) . cloned ( ) ) ,
48+ } )
49+ } else {
50+ Box :: new ( std:: iter:: empty ( ) )
51+ }
52+ }
53+
54+ /// Iterate starting from `snapshot` (inclusive) to `oldest_snapshot_id` (exclusive).
55+ pub fn ancestors_between (
56+ table_metadata : & TableMetadataRef ,
57+ latest_snapshot_id : i64 ,
58+ oldest_snapshot_id : Option < i64 > ,
59+ ) -> Box < dyn Iterator < Item = SnapshotRef > + Send > {
60+ let Some ( oldest_snapshot_id) = oldest_snapshot_id else {
61+ return Box :: new ( ancestors_of ( table_metadata, latest_snapshot_id) ) ;
62+ } ;
63+
64+ if latest_snapshot_id == oldest_snapshot_id {
65+ return Box :: new ( std:: iter:: empty ( ) ) ;
66+ }
67+
68+ Box :: new (
69+ ancestors_of ( table_metadata, latest_snapshot_id)
70+ . take_while ( move |snapshot| snapshot. snapshot_id ( ) != oldest_snapshot_id) ,
71+ )
72+ }
0 commit comments