use crate::transaction::{Operation, UpdateMap};
use std::collections::HashSet;
impl PartialEq for Operation {
fn eq(&self, other: &Self) -> bool {
fn compare_vec<T: PartialEq>(a: &[T], b: &[T]) -> bool {
a.len() == b.len() && a.iter().all(|f| b.contains(f))
}
match (self, other) {
(Self::Append { fragments: a }, Self::Append { fragments: b }) => compare_vec(a, b),
(
Self::Clone {
is_shallow: a_is_shallow,
ref_name: a_ref_name,
ref_version: a_ref_version,
ref_path: a_source_path,
branch_name: a_branch_name,
},
Self::Clone {
is_shallow: b_is_shallow,
ref_name: b_ref_name,
ref_version: b_ref_version,
ref_path: b_source_path,
branch_name: b_branch_name,
},
) => {
a_is_shallow == b_is_shallow
&& a_ref_name == b_ref_name
&& a_ref_version == b_ref_version
&& a_source_path == b_source_path
&& a_branch_name == b_branch_name
}
(
Self::Delete {
updated_fragments: a_updated,
deleted_fragment_ids: a_deleted,
predicate: a_predicate,
},
Self::Delete {
updated_fragments: b_updated,
deleted_fragment_ids: b_deleted,
predicate: b_predicate,
},
) => {
compare_vec(a_updated, b_updated)
&& compare_vec(a_deleted, b_deleted)
&& a_predicate == b_predicate
}
(
Self::Overwrite {
fragments: a_fragments,
schema: a_schema,
config_upsert_values: a_config,
initial_bases: a_initial,
},
Self::Overwrite {
fragments: b_fragments,
schema: b_schema,
config_upsert_values: b_config,
initial_bases: b_initial,
},
) => {
compare_vec(a_fragments, b_fragments)
&& a_schema == b_schema
&& a_config == b_config
&& a_initial == b_initial
}
(
Self::CreateIndex {
new_indices: a_new,
removed_indices: a_removed,
},
Self::CreateIndex {
new_indices: b_new,
removed_indices: b_removed,
},
) => compare_vec(a_new, b_new) && compare_vec(a_removed, b_removed),
(
Self::Rewrite {
groups: a_groups,
rewritten_indices: a_indices,
frag_reuse_index: a_frag_reuse_index,
},
Self::Rewrite {
groups: b_groups,
rewritten_indices: b_indices,
frag_reuse_index: b_frag_reuse_index,
},
) => {
compare_vec(a_groups, b_groups)
&& compare_vec(a_indices, b_indices)
&& a_frag_reuse_index == b_frag_reuse_index
}
(
Self::Merge {
fragments: a_fragments,
schema: a_schema,
preserves_nullability: a_preserves,
},
Self::Merge {
fragments: b_fragments,
schema: b_schema,
preserves_nullability: b_preserves,
},
) => {
compare_vec(a_fragments, b_fragments)
&& a_schema == b_schema
&& a_preserves == b_preserves
}
(Self::Restore { version: a }, Self::Restore { version: b }) => a == b,
(
Self::ReserveFragments { num_fragments: a },
Self::ReserveFragments { num_fragments: b },
) => a == b,
(
Self::Update {
removed_fragment_ids: a_removed,
updated_fragments: a_updated,
new_fragments: a_new,
fields_modified: a_fields,
compacted_sstables: a_compacted_sstables,
fields_for_preserving_frag_bitmap: a_fields_for_preserving_frag_bitmap,
update_mode: a_update_mode,
inserted_rows_filter: a_inserted_rows_filter,
updated_fragment_offsets: a_updated_fragment_offsets,
},
Self::Update {
removed_fragment_ids: b_removed,
updated_fragments: b_updated,
new_fragments: b_new,
fields_modified: b_fields,
compacted_sstables: b_compacted_sstables,
fields_for_preserving_frag_bitmap: b_fields_for_preserving_frag_bitmap,
update_mode: b_update_mode,
inserted_rows_filter: b_inserted_rows_filter,
updated_fragment_offsets: b_updated_fragment_offsets,
},
) => {
compare_vec(a_removed, b_removed)
&& compare_vec(a_updated, b_updated)
&& compare_vec(a_new, b_new)
&& compare_vec(a_fields, b_fields)
&& compare_vec(a_compacted_sstables, b_compacted_sstables)
&& compare_vec(
a_fields_for_preserving_frag_bitmap,
b_fields_for_preserving_frag_bitmap,
)
&& a_update_mode == b_update_mode
&& a_inserted_rows_filter == b_inserted_rows_filter
&& a_updated_fragment_offsets == b_updated_fragment_offsets
}
(
Self::Project {
schema: a,
preserves_nullability: a_preserves,
},
Self::Project {
schema: b,
preserves_nullability: b_preserves,
},
) => a == b && a_preserves == b_preserves,
(
Self::UpdateConfig {
config_updates: a_config,
table_metadata_updates: a_table_metadata,
schema_metadata_updates: a_schema,
field_metadata_updates: a_field,
},
Self::UpdateConfig {
config_updates: b_config,
table_metadata_updates: b_table_metadata,
schema_metadata_updates: b_schema,
field_metadata_updates: b_field,
},
) => {
a_config == b_config
&& a_table_metadata == b_table_metadata
&& a_schema == b_schema
&& a_field == b_field
}
(
Self::DataReplacement { replacements: a },
Self::DataReplacement { replacements: b },
) => a.len() == b.len() && a.iter().all(|r| b.contains(r)),
(Self::Append { .. }, Self::Delete { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Append { .. }, Self::Overwrite { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Append { .. }, Self::CreateIndex { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Append { .. }, Self::Rewrite { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Append { .. }, Self::Merge { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Append { .. }, Self::Restore { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Append { .. }, Self::ReserveFragments { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Append { .. }, Self::Update { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Append { .. }, Self::Project { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Append { .. }, Self::UpdateConfig { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Append { .. }, Self::DataReplacement { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Append { .. }, Self::UpdateMemWalState { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Append { .. }, Self::Clone { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Delete { .. }, Self::Append { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Delete { .. }, Self::Overwrite { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Delete { .. }, Self::CreateIndex { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Delete { .. }, Self::Rewrite { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Delete { .. }, Self::Merge { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Delete { .. }, Self::Restore { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Delete { .. }, Self::ReserveFragments { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Delete { .. }, Self::Update { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Delete { .. }, Self::Project { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Delete { .. }, Self::UpdateConfig { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Delete { .. }, Self::DataReplacement { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Delete { .. }, Self::UpdateMemWalState { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Delete { .. }, Self::Clone { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Overwrite { .. }, Self::Append { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Overwrite { .. }, Self::Delete { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Overwrite { .. }, Self::CreateIndex { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Overwrite { .. }, Self::Rewrite { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Overwrite { .. }, Self::Merge { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Overwrite { .. }, Self::Restore { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Overwrite { .. }, Self::ReserveFragments { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Overwrite { .. }, Self::Update { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Overwrite { .. }, Self::Project { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Overwrite { .. }, Self::UpdateConfig { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Overwrite { .. }, Self::DataReplacement { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Overwrite { .. }, Self::UpdateMemWalState { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Overwrite { .. }, Self::Clone { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::CreateIndex { .. }, Self::Append { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::CreateIndex { .. }, Self::Delete { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::CreateIndex { .. }, Self::Overwrite { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::CreateIndex { .. }, Self::Rewrite { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::CreateIndex { .. }, Self::Merge { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::CreateIndex { .. }, Self::Restore { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::CreateIndex { .. }, Self::ReserveFragments { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::CreateIndex { .. }, Self::Update { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::CreateIndex { .. }, Self::Project { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::CreateIndex { .. }, Self::UpdateConfig { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::CreateIndex { .. }, Self::DataReplacement { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::CreateIndex { .. }, Self::UpdateMemWalState { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::CreateIndex { .. }, Self::Clone { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Rewrite { .. }, Self::Append { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Rewrite { .. }, Self::Delete { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Rewrite { .. }, Self::Overwrite { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Rewrite { .. }, Self::CreateIndex { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Rewrite { .. }, Self::Merge { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Rewrite { .. }, Self::Restore { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Rewrite { .. }, Self::ReserveFragments { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Rewrite { .. }, Self::Update { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Rewrite { .. }, Self::Project { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Rewrite { .. }, Self::UpdateConfig { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Rewrite { .. }, Self::DataReplacement { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Rewrite { .. }, Self::UpdateMemWalState { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Rewrite { .. }, Self::Clone { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Merge { .. }, Self::Append { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Merge { .. }, Self::Delete { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Merge { .. }, Self::Overwrite { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Merge { .. }, Self::CreateIndex { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Merge { .. }, Self::Rewrite { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Merge { .. }, Self::Restore { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Merge { .. }, Self::ReserveFragments { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Merge { .. }, Self::Update { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Merge { .. }, Self::Project { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Merge { .. }, Self::UpdateConfig { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Merge { .. }, Self::DataReplacement { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Merge { .. }, Self::UpdateMemWalState { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Merge { .. }, Self::Clone { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Restore { .. }, Self::Append { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Restore { .. }, Self::Delete { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Restore { .. }, Self::Overwrite { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Restore { .. }, Self::CreateIndex { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Restore { .. }, Self::Rewrite { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Restore { .. }, Self::Merge { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Restore { .. }, Self::ReserveFragments { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Restore { .. }, Self::Update { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Restore { .. }, Self::Project { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Restore { .. }, Self::UpdateConfig { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Restore { .. }, Self::DataReplacement { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Restore { .. }, Self::UpdateMemWalState { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Restore { .. }, Self::Clone { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::ReserveFragments { .. }, Self::Append { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::ReserveFragments { .. }, Self::Delete { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::ReserveFragments { .. }, Self::Overwrite { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::ReserveFragments { .. }, Self::CreateIndex { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::ReserveFragments { .. }, Self::Rewrite { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::ReserveFragments { .. }, Self::Merge { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::ReserveFragments { .. }, Self::Restore { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::ReserveFragments { .. }, Self::Update { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::ReserveFragments { .. }, Self::Project { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::ReserveFragments { .. }, Self::UpdateConfig { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::ReserveFragments { .. }, Self::DataReplacement { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::ReserveFragments { .. }, Self::UpdateMemWalState { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::ReserveFragments { .. }, Self::Clone { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Update { .. }, Self::Append { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Update { .. }, Self::Delete { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Update { .. }, Self::Overwrite { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Update { .. }, Self::CreateIndex { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Update { .. }, Self::Rewrite { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Update { .. }, Self::Merge { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Update { .. }, Self::Restore { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Update { .. }, Self::ReserveFragments { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Update { .. }, Self::Project { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Update { .. }, Self::UpdateConfig { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Update { .. }, Self::DataReplacement { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Update { .. }, Self::UpdateMemWalState { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Update { .. }, Self::Clone { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Project { .. }, Self::Append { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Project { .. }, Self::Delete { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Project { .. }, Self::Overwrite { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Project { .. }, Self::CreateIndex { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Project { .. }, Self::Rewrite { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Project { .. }, Self::Merge { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Project { .. }, Self::Restore { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Project { .. }, Self::ReserveFragments { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Project { .. }, Self::Update { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Project { .. }, Self::UpdateConfig { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Project { .. }, Self::DataReplacement { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Project { .. }, Self::UpdateMemWalState { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Project { .. }, Self::Clone { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateConfig { .. }, Self::Append { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateConfig { .. }, Self::Delete { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateConfig { .. }, Self::Overwrite { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateConfig { .. }, Self::CreateIndex { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateConfig { .. }, Self::Rewrite { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateConfig { .. }, Self::Merge { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateConfig { .. }, Self::Restore { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateConfig { .. }, Self::ReserveFragments { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateConfig { .. }, Self::Update { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateConfig { .. }, Self::Project { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateConfig { .. }, Self::DataReplacement { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateConfig { .. }, Self::UpdateMemWalState { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateConfig { .. }, Self::Clone { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::DataReplacement { .. }, Self::Append { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::DataReplacement { .. }, Self::Delete { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::DataReplacement { .. }, Self::Overwrite { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::DataReplacement { .. }, Self::CreateIndex { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::DataReplacement { .. }, Self::Rewrite { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::DataReplacement { .. }, Self::Merge { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::DataReplacement { .. }, Self::Restore { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::DataReplacement { .. }, Self::ReserveFragments { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::DataReplacement { .. }, Self::Update { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::DataReplacement { .. }, Self::Project { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::DataReplacement { .. }, Self::UpdateConfig { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::DataReplacement { .. }, Self::UpdateMemWalState { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::DataReplacement { .. }, Self::Clone { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateMemWalState { .. }, Self::Append { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateMemWalState { .. }, Self::Delete { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateMemWalState { .. }, Self::Overwrite { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateMemWalState { .. }, Self::CreateIndex { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateMemWalState { .. }, Self::Rewrite { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateMemWalState { .. }, Self::Merge { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateMemWalState { .. }, Self::Restore { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateMemWalState { .. }, Self::ReserveFragments { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateMemWalState { .. }, Self::Update { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateMemWalState { .. }, Self::Project { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateMemWalState { .. }, Self::UpdateConfig { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateMemWalState { .. }, Self::DataReplacement { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateMemWalState { .. }, Self::Clone { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(
Self::UpdateMemWalState {
compacted_sstables: a_compacted,
},
Self::UpdateMemWalState {
compacted_sstables: b_compacted,
},
) => compare_vec(a_compacted, b_compacted),
(Self::Clone { .. }, Self::Append { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Clone { .. }, Self::Delete { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Clone { .. }, Self::Overwrite { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Clone { .. }, Self::CreateIndex { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Clone { .. }, Self::Rewrite { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Clone { .. }, Self::Merge { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Clone { .. }, Self::Restore { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Clone { .. }, Self::ReserveFragments { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Clone { .. }, Self::Update { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Clone { .. }, Self::Project { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Clone { .. }, Self::UpdateConfig { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Clone { .. }, Self::DataReplacement { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Clone { .. }, Self::UpdateMemWalState { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateBases { new_bases: a }, Self::UpdateBases { new_bases: b }) => {
compare_vec(a, b)
}
(Self::UpdateBases { .. }, Self::Append { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateBases { .. }, Self::Delete { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateBases { .. }, Self::Overwrite { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateBases { .. }, Self::CreateIndex { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateBases { .. }, Self::Rewrite { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateBases { .. }, Self::Merge { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateBases { .. }, Self::Restore { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateBases { .. }, Self::ReserveFragments { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateBases { .. }, Self::Update { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateBases { .. }, Self::Project { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateBases { .. }, Self::UpdateConfig { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateBases { .. }, Self::DataReplacement { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateBases { .. }, Self::UpdateMemWalState { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateBases { .. }, Self::Clone { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Append { .. }, Self::UpdateBases { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Delete { .. }, Self::UpdateBases { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Overwrite { .. }, Self::UpdateBases { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::CreateIndex { .. }, Self::UpdateBases { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Rewrite { .. }, Self::UpdateBases { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Merge { .. }, Self::UpdateBases { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Restore { .. }, Self::UpdateBases { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::ReserveFragments { .. }, Self::UpdateBases { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Update { .. }, Self::UpdateBases { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Project { .. }, Self::UpdateBases { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateConfig { .. }, Self::UpdateBases { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::DataReplacement { .. }, Self::UpdateBases { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::UpdateMemWalState { .. }, Self::UpdateBases { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::Clone { .. }, Self::UpdateBases { .. }) => {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
(Self::DataOverlay { groups: a }, Self::DataOverlay { groups: b }) => compare_vec(a, b),
(Self::DataOverlay { .. }, _) | (_, Self::DataOverlay { .. }) => false,
}
}
}
impl Operation {
fn get_upsert_config_keys(&self) -> Vec<String> {
match self {
Self::Overwrite {
config_upsert_values: Some(upsert_values),
..
} => {
let vec: Vec<String> = upsert_values.keys().cloned().collect();
vec
}
Self::UpdateConfig {
config_updates: Some(config_updates),
..
} => config_updates
.update_entries
.iter()
.filter_map(|entry| {
if entry.value.is_some() {
Some(entry.key.clone())
} else {
None
}
})
.collect(),
_ => Vec::<String>::new(),
}
}
fn get_delete_config_keys(&self) -> Vec<String> {
match self {
Self::UpdateConfig {
config_updates: Some(config_updates),
..
} => config_updates
.update_entries
.iter()
.filter_map(|entry| {
if entry.value.is_none() {
Some(entry.key.clone())
} else {
None
}
})
.collect(),
_ => Vec::<String>::new(),
}
}
pub fn modifies_same_metadata(&self, other: &Self) -> bool {
match (self, other) {
(
Self::UpdateConfig {
table_metadata_updates,
schema_metadata_updates,
field_metadata_updates,
..
},
Self::UpdateConfig {
table_metadata_updates: other_table_metadata,
schema_metadata_updates: other_schema_metadata,
field_metadata_updates: other_field_metadata,
..
},
) => {
if Self::update_maps_conflict(
table_metadata_updates.as_ref(),
other_table_metadata.as_ref(),
) {
return true;
}
if schema_metadata_updates.is_some() && other_schema_metadata.is_some() {
return true;
}
if !field_metadata_updates.is_empty() && !other_field_metadata.is_empty() {
for field in field_metadata_updates.keys() {
if other_field_metadata.contains_key(field) {
return true;
}
}
}
false
}
_ => false,
}
}
fn update_maps_conflict(left: Option<&UpdateMap>, right: Option<&UpdateMap>) -> bool {
let (Some(left), Some(right)) = (left, right) else {
return false;
};
if left.replace || right.replace {
return true;
}
let left_keys = left
.update_entries
.iter()
.map(|entry| entry.key.as_str())
.collect::<HashSet<_>>();
right
.update_entries
.iter()
.any(|entry| left_keys.contains(entry.key.as_str()))
}
pub fn upsert_key_conflict(&self, other: &Self) -> bool {
let self_upsert_keys = self.get_upsert_config_keys();
let other_upsert_keys = other.get_upsert_config_keys();
let self_delete_keys = self.get_delete_config_keys();
let other_delete_keys = other.get_delete_config_keys();
self_upsert_keys
.iter()
.any(|x| other_upsert_keys.contains(x) || other_delete_keys.contains(x))
|| other_upsert_keys
.iter()
.any(|x| self_upsert_keys.contains(x) || self_delete_keys.contains(x))
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::transaction::test_support::overlay_with_field;
use crate::transaction::{DataOverlayGroup, UpdateMapEntry};
use std::collections::HashMap;
fn table_metadata_update(entries: Vec<(&str, Option<&str>)>, replace: bool) -> Operation {
Operation::UpdateConfig {
config_updates: None,
table_metadata_updates: Some(UpdateMap {
update_entries: entries.into_iter().map(UpdateMapEntry::from).collect(),
replace,
}),
schema_metadata_updates: None,
field_metadata_updates: HashMap::new(),
}
}
#[test]
fn test_table_metadata_conflicts_on_same_key() {
let left = table_metadata_update(vec![("key", Some("1"))], false);
let same_key = table_metadata_update(vec![("key", Some("2"))], false);
let different_key = table_metadata_update(vec![("other", Some("2"))], false);
let replace = table_metadata_update(vec![("other", Some("2"))], true);
assert!(left.modifies_same_metadata(&same_key));
assert!(!left.modifies_same_metadata(&different_key));
assert!(left.modifies_same_metadata(&replace));
}
#[test]
fn test_data_overlay_operation_eq() {
let overlay = |field: i32| Operation::DataOverlay {
groups: vec![DataOverlayGroup {
fragment_id: 0,
overlays: vec![overlay_with_field(field, 1)],
}],
};
assert_eq!(overlay(1), overlay(1));
assert_ne!(overlay(1), overlay(2));
let rewrite = Operation::Rewrite {
groups: vec![],
rewritten_indices: vec![],
frag_reuse_index: None,
};
assert_ne!(overlay(1), rewrite);
}
}