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