Creates hashes for the given arrays using a thread-local buffer, then calls the provided callback with an immutable reference to the computed hashes. This function manages a thread-local buffer to avoid repeated allocations. The buffer is automatically truncated if it exceeds `MAX_BUFFER_SIZE` after use. # Arguments `arrays` - The arrays to hash (must contain at least one array) `random_state` -
(
arrays: I,
random_state: &RandomState,
callback: F,
)
| 98 | /// })?; |
| 99 | /// ``` |
| 100 | pub fn with_hashes<I, T, F, R>( |
| 101 | arrays: I, |
| 102 | random_state: &RandomState, |
| 103 | callback: F, |
| 104 | ) -> Result<R> |
| 105 | where |
| 106 | I: IntoIterator<Item = T>, |
| 107 | T: AsDynArray, |
| 108 | F: FnOnce(&[u64]) -> Result<R>, |
| 109 | { |
| 110 | // Peek at the first array to determine buffer size without fully collecting |
| 111 | let mut iter = arrays.into_iter().peekable(); |
| 112 | |
| 113 | // Get the required size from the first array |
| 114 | let required_size = match iter.peek() { |
| 115 | Some(arr) => arr.as_dyn_array().len(), |
| 116 | None => return _internal_err!("with_hashes requires at least one array"), |
| 117 | }; |
| 118 | |
| 119 | HASH_BUFFER.try_with(|cell| { |
| 120 | let mut buffer = cell.try_borrow_mut() |
| 121 | .map_err(|_| _internal_datafusion_err!("with_hashes cannot be called reentrantly on the same thread"))?; |
| 122 | |
| 123 | // Ensure buffer has sufficient length, clearing old values |
| 124 | buffer.clear(); |
| 125 | buffer.resize(required_size, 0); |
| 126 | |
| 127 | // Create hashes in the buffer - this consumes the iterator |
| 128 | create_hashes(iter, random_state, &mut buffer[..required_size])?; |
| 129 | |
| 130 | // Execute the callback with an immutable slice |
| 131 | let result = callback(&buffer[..required_size])?; |
| 132 | |
| 133 | // Cleanup: truncate if buffer grew too large |
| 134 | if buffer.capacity() > MAX_BUFFER_SIZE { |
| 135 | buffer.truncate(MAX_BUFFER_SIZE); |
| 136 | buffer.shrink_to_fit(); |
| 137 | } |
| 138 | |
| 139 | Ok(result) |
| 140 | }).map_err(|_| _internal_datafusion_err!("with_hashes cannot access thread-local storage during or after thread destruction"))? |
| 141 | } |
| 142 | |
| 143 | #[cfg(not(feature = "force_hash_collisions"))] |
| 144 | fn hash_null(random_state: &RandomState, hashes_buffer: &'_ mut [u64], mul_col: bool) { |
searching dependent graphs…