MCPcopy Create free account
hub / github.com/apache/arrow-rs / try_append_value

Method try_append_value

arrow-array/src/builder/generic_bytes_view_builder.rs:339–422  ·  view source on GitHub ↗
(&mut self, value: impl AsRef<T::Native>)

Source from the content-addressed store, hash-verified

337 /// - String length exceeds `u32::MAX`
338 #[inline]
339 pub fn try_append_value(&mut self, value: impl AsRef<T::Native>) -> Result<(), ArrowError> {
340 let v: &[u8] = value.as_ref().as_ref();
341 let length: u32 = v.len().try_into().map_err(|_| {
342 ArrowError::InvalidArgumentError(format!("String length {} exceeds u32::MAX", v.len()))
343 })?;
344
345 if length <= MAX_INLINE_VIEW_LEN {
346 let mut view_buffer = [0; 16];
347 view_buffer[0..4].copy_from_slice(&length.to_le_bytes());
348 view_buffer[4..4 + v.len()].copy_from_slice(v);
349 self.views_buffer.push(u128::from_le_bytes(view_buffer));
350 self.null_buffer_builder.append_non_null();
351 return Ok(());
352 }
353
354 // Deduplication if:
355 // (1) deduplication is enabled.
356 // (2) len > `MAX_INLINE_VIEW_LEN` and len <= `max_deduplication_len`
357 let can_deduplicate = self.string_tracker.is_some()
358 && self
359 .max_deduplication_len
360 .map(|max_length| length <= max_length)
361 .unwrap_or(true);
362 if can_deduplicate {
363 if let Some((mut ht, hasher)) = self.string_tracker.take() {
364 let hash_val = hasher.hash_one(v);
365 let hasher_fn = |v: &_| hasher.hash_one(v);
366
367 let entry = ht.entry(
368 hash_val,
369 |idx| {
370 let stored_value = self.get_value(*idx);
371 v == stored_value
372 },
373 hasher_fn,
374 );
375 match entry {
376 Entry::Occupied(occupied) => {
377 // If the string already exists, we will directly use the view
378 let idx = occupied.get();
379 self.views_buffer.push(self.views_buffer[*idx]);
380 self.null_buffer_builder.append_non_null();
381 self.string_tracker = Some((ht, hasher));
382 return Ok(());
383 }
384 Entry::Vacant(vacant) => {
385 // o.w. we insert the (string hash -> view index)
386 // the idx is current length of views_builder, as we are inserting a new view
387 vacant.insert(self.views_buffer.len());
388 }
389 }
390 self.string_tracker = Some((ht, hasher));
391 }
392 }
393
394 let required_cap = self.in_progress.len() + v.len();
395 if self.in_progress.capacity() < required_cap {
396 self.flush_in_progress();

Callers 4

append_valueMethod · 0.45
try_append_value_nMethod · 0.45

Calls 15

append_non_nullMethod · 0.80
flush_in_progressMethod · 0.80
maxMethod · 0.80
extend_from_sliceMethod · 0.80
as_refMethod · 0.45
lenMethod · 0.45
to_le_bytesMethod · 0.45
pushMethod · 0.45
takeMethod · 0.45
get_valueMethod · 0.45
getMethod · 0.45
insertMethod · 0.45

Tested by

no test coverage detected