Skip to content

Commit

Permalink
fix rebase
Browse files Browse the repository at this point in the history
  • Loading branch information
ZENOTME committed Feb 24, 2025
1 parent 3e958e2 commit df3dd40
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 84 deletions.
2 changes: 1 addition & 1 deletion crates/iceberg/src/spec/schema/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use std::sync::Arc;

mod utils;
mod visitor;
pub use self::visitor::{visit_schema, visit_struct, visit_type, SchemaVisitor};
pub use self::visitor::*;
pub(super) mod _serde;
mod id_reassigner;
mod index;
Expand Down
118 changes: 35 additions & 83 deletions crates/iceberg/src/spec/schema/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,12 +162,6 @@ pub trait SchemaWithPartnerVisitor<P> {
Ok(())
}

/// Called before every type, if this function return `Some`, the following visiting will be skipped.
/// This function used to implement early return.
fn visit_type_before(&mut self, _ty: &Type, _partner: &P) -> Result<Option<Self::T>> {
return Ok(None);
}

/// Called after schema's type visited.
fn schema(&mut self, schema: &Schema, partner: &P, value: Self::T) -> Result<Self::T>;
/// Called after struct's field type visited.
Expand All @@ -180,47 +174,31 @@ pub trait SchemaWithPartnerVisitor<P> {
results: Vec<Self::T>,
) -> Result<Self::T>;
/// Called after list fields visited.
fn list(&mut self, list: &ListType, partner: &P, value: Vec<Self::T>) -> Result<Self::T>;
fn list(&mut self, list: &ListType, partner: &P, value: Self::T) -> Result<Self::T>;
/// Called after map's key and value fields visited.
fn map(
&mut self,
map: &MapType,
partner: &P,
key_value: Vec<Self::T>,
value: Vec<Self::T>,
key_value: Self::T,
value: Self::T,
) -> Result<Self::T>;
/// Called when see a primitive type.
fn primitive(&mut self, p: &PrimitiveType, partner: &P) -> Result<Self::T>;
}

/// Accessor used to get child partner from parent partner.
pub trait PartnerAccessor<P> {
/// List partner iterator.
type L: ListPartnerIterator<P>;
/// Map partner iterator.
type M: MapPartnerIterator<P>;

/// Get the struct partner from schema partner.
fn struct_parner<'a>(&self, schema_partner: &'a P) -> Result<&'a P>;
/// Get the field partner from struct partner.
fn field_partner<'a>(&self, struct_partner: &'a P, field_id: i32, field: &str)
-> Result<&'a P>;
fn field_partner<'a>(&self, struct_partner: &'a P, field: &NestedField) -> Result<&'a P>;
/// Get the list element partner from list partner.
fn list_element_partner<'a>(&self, list_partner: &'a P) -> Result<Self::L>;
fn list_element_partner<'a>(&self, list_partner: &'a P) -> Result<&'a P>;
/// Get the map key partner from map partner.
fn map_element_partner<'a>(&self, map_partner: &'a P) -> Result<Self::M>;
}

/// Iterator for list partner.
pub trait ListPartnerIterator<P> {
/// Get the next partner.
fn next(&mut self) -> Option<P>;
}

/// Iterator for map partner.
pub trait MapPartnerIterator<P> {
/// Get the next partner.
fn next(&mut self) -> Option<(P, P)>;
fn map_key_partner<'a>(&self, map_partner: &'a P) -> Result<&'a P>;
/// Get the map value partner from map partner.
fn map_value_partner<'a>(&self, map_partner: &'a P) -> Result<&'a P>;
}

/// Visiting a type in post order.
Expand All @@ -230,61 +208,38 @@ pub fn visit_type_with_partner<P, V: SchemaWithPartnerVisitor<P>, A: PartnerAcce
visitor: &mut V,
accessor: &A,
) -> Result<V::T> {
if let Some(res) = visitor.visit_type_before(r#type, partner)? {
return Ok(res);
}
match r#type {
Type::Primitive(p) => visitor.primitive(p, partner),
Type::List(list) => {
let mut results = Vec::new();
let mut list_element_partner_iter = accessor.list_element_partner(partner)?;
if let Some(list_element_partner) = list_element_partner_iter.next() {
visitor.before_list_element(&list.element_field, &list_element_partner)?;
let value = visit_type_with_partner(
&list.element_field.field_type,
&list_element_partner,
visitor,
accessor,
)?;
visitor.after_list_element(&list.element_field, &list_element_partner)?;
results.push(value);
}
visitor.list(list, partner, results)
let list_element_partner = accessor.list_element_partner(partner)?;
visitor.before_list_element(&list.element_field, list_element_partner)?;
let element_results = visit_type_with_partner(
&list.element_field.field_type,
list_element_partner,
visitor,
accessor,
)?;
visitor.after_list_element(&list.element_field, list_element_partner)?;
visitor.list(list, partner, element_results)
}
Type::Map(map) => {
let mut k_results = Vec::new();
let mut v_results = Vec::new();
let mut kv_partner_iter = accessor.map_element_partner(partner)?;
if let Some((k_partner, v_partner)) = kv_partner_iter.next() {
let key_result = {
visitor.before_map_key(&map.key_field, &k_partner)?;
let ret = visit_type_with_partner(
&map.key_field.field_type,
&k_partner,
visitor,
accessor,
)?;
visitor.after_map_key(&map.key_field, &k_partner)?;
ret
};

let value_result = {
visitor.before_map_value(&map.value_field, &v_partner)?;
let ret = visit_type_with_partner(
&map.value_field.field_type,
&v_partner,
visitor,
accessor,
)?;
visitor.after_map_value(&map.value_field, &v_partner)?;
ret
};
let key_partner = accessor.map_key_partner(partner)?;
visitor.before_map_key(&map.key_field, key_partner)?;
let key_result =
visit_type_with_partner(&map.key_field.field_type, key_partner, visitor, accessor)?;
visitor.after_map_key(&map.key_field, key_partner)?;

k_results.push(key_result);
v_results.push(value_result);
}
let value_partner = accessor.map_value_partner(partner)?;
visitor.before_map_value(&map.value_field, value_partner)?;
let value_result = visit_type_with_partner(
&map.value_field.field_type,
value_partner,
visitor,
accessor,
)?;
visitor.after_map_value(&map.value_field, value_partner)?;

visitor.map(map, partner, k_results, v_results)
visitor.map(map, partner, key_result, value_result)
}
Type::Struct(s) => visit_struct_with_partner(s, partner, visitor, accessor),
}
Expand All @@ -297,12 +252,9 @@ pub fn visit_struct_with_partner<P, V: SchemaWithPartnerVisitor<P>, A: PartnerAc
visitor: &mut V,
accessor: &A,
) -> Result<V::T> {
if let Some(res) = visitor.visit_type_before(&Type::Struct(s.clone()), partner)? {
return Ok(res);
}
let mut results = Vec::with_capacity(s.fields().len());
for field in s.fields() {
let field_partner = accessor.field_partner(partner, field.id, &field.name)?;
let field_partner = accessor.field_partner(partner, field)?;
visitor.before_struct_field(field, field_partner)?;
let result = visit_type_with_partner(&field.field_type, field_partner, visitor, accessor)?;
visitor.after_struct_field(field, field_partner)?;
Expand All @@ -327,4 +279,4 @@ pub fn visit_schema_with_partner<P, V: SchemaWithPartnerVisitor<P>, A: PartnerAc
accessor,
)?;
visitor.schema(schema, partner, result)
}
}

0 comments on commit df3dd40

Please sign in to comment.