Skip to content

Commit f5f09ea

Browse files
scovichalamb
andauthored
Finish implementing Variant::Object and Variant::List (#7666)
# Which issue does this PR close? - Closes #7665 # Rationale for this change Continuing the ongoing variant implementation effort. # What changes are included in this PR? As per title -- implement fairly complete support for variant objects and arrays. Also add some unit tests. Note: This PR renames `VariantArray` as `VariantList` to align with parquet and arrow terminology, and to not conflict with the `VariantArray` we will eventually need to define for holding an arrow array of variant-typed data. # Are there any user-facing changes? Those variant subtypes should now be usable. --------- Co-authored-by: Andrew Lamb <[email protected]>
1 parent 639b5bb commit f5f09ea

File tree

3 files changed

+719
-103
lines changed

3 files changed

+719
-103
lines changed

parquet-variant/src/utils.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,45 @@ pub(crate) fn string_from_slice(slice: &[u8], range: Range<usize>) -> Result<&st
5757
str::from_utf8(slice_from_slice(slice, range)?)
5858
.map_err(|_| ArrowError::InvalidArgumentError("invalid UTF-8 string".to_string()))
5959
}
60+
61+
/// Performs a binary search on a slice using a fallible key extraction function.
62+
///
63+
/// This is similar to the standard library's `binary_search_by`, but allows the key
64+
/// extraction function to fail. If key extraction fails during the search, that error
65+
/// is propagated immediately.
66+
///
67+
/// # Arguments
68+
/// * `slice` - The slice to search in
69+
/// * `target` - The target value to search for
70+
/// * `key_extractor` - A function that extracts a comparable key from slice elements.
71+
/// This function can fail and return an error.
72+
///
73+
/// # Returns
74+
/// * `Ok(Ok(index))` - Element found at the given index
75+
/// * `Ok(Err(index))` - Element not found, but would be inserted at the given index
76+
/// * `Err(e)` - Key extraction failed with error `e`
77+
pub(crate) fn try_binary_search_by<T, K, E, F>(
78+
slice: &[T],
79+
target: &K,
80+
mut key_extractor: F,
81+
) -> Result<Result<usize, usize>, E>
82+
where
83+
K: Ord,
84+
F: FnMut(&T) -> Result<K, E>,
85+
{
86+
let mut left = 0;
87+
let mut right = slice.len();
88+
89+
while left < right {
90+
let mid = (left + right) / 2;
91+
let key = key_extractor(&slice[mid])?;
92+
93+
match key.cmp(target) {
94+
std::cmp::Ordering::Equal => return Ok(Ok(mid)),
95+
std::cmp::Ordering::Greater => right = mid,
96+
std::cmp::Ordering::Less => left = mid + 1,
97+
}
98+
}
99+
100+
Ok(Err(left))
101+
}

0 commit comments

Comments
 (0)