Path: blob/main/crates/polars-core/src/series/builder.rs
6940 views
use arrow::array::builder::{ArrayBuilder, ShareStrategy, make_builder};1use polars_utils::IdxSize;23#[cfg(feature = "object")]4use crate::chunked_array::object::registry::get_object_builder;5use crate::prelude::*;6use crate::utils::Container;78/// A type-erased wrapper around ArrayBuilder.9pub struct SeriesBuilder {10dtype: DataType,11builder: Box<dyn ArrayBuilder>,12}1314impl SeriesBuilder {15pub fn new(dtype: DataType) -> Self {16// FIXME: get rid of this hack.17#[cfg(feature = "object")]18if matches!(dtype, DataType::Object(_)) {19let builder = get_object_builder(PlSmallStr::EMPTY, 0).as_array_builder();20return Self { dtype, builder };21}2223let builder = make_builder(&dtype.to_physical().to_arrow(CompatLevel::newest()));24Self { dtype, builder }25}2627#[inline(always)]28pub fn reserve(&mut self, additional: usize) {29self.builder.reserve(additional);30}3132pub fn freeze(self, name: PlSmallStr) -> Series {33unsafe {34Series::from_chunks_and_dtype_unchecked(name, vec![self.builder.freeze()], &self.dtype)35}36}3738pub fn freeze_reset(&mut self, name: PlSmallStr) -> Series {39unsafe {40Series::from_chunks_and_dtype_unchecked(41name,42vec![self.builder.freeze_reset()],43&self.dtype,44)45}46}4748pub fn len(&self) -> usize {49self.builder.len()50}5152pub fn is_empty(&self) -> bool {53self.builder.len() == 054}5556pub fn dtype(&self) -> &DataType {57&self.dtype58}59/// Extend this builder with the given number of null elements.60pub fn extend_nulls(&mut self, length: usize) {61self.builder.extend_nulls(length);62}6364/// Extends this builder with the contents of the given series. May panic if65/// other does not match the dtype of this builder.66#[inline(always)]67pub fn extend(&mut self, other: &Series, share: ShareStrategy) {68self.subslice_extend(other, 0, other.len(), share);69}7071/// Extends this builder with the contents of the given series subslice.72/// May panic if other does not match the dtype of this builder.73pub fn subslice_extend(74&mut self,75other: &Series,76mut start: usize,77mut length: usize,78share: ShareStrategy,79) {80if length == 0 || other.is_empty() {81return;82}8384for chunk in other.chunks() {85if start < chunk.len() {86let length_in_chunk = length.min(chunk.len() - start);87self.builder88.subslice_extend(&**chunk, start, length_in_chunk, share);8990start = 0;91length -= length_in_chunk;92if length == 0 {93break;94}95} else {96start -= chunk.len();97}98}99}100101pub fn subslice_extend_repeated(102&mut self,103other: &Series,104start: usize,105length: usize,106repeats: usize,107share: ShareStrategy,108) {109if length == 0 || other.is_empty() {110return;111}112113let chunks = other.chunks();114if chunks.len() == 1 {115self.builder116.subslice_extend_repeated(&*chunks[0], start, length, repeats, share);117} else {118for _ in 0..repeats {119self.subslice_extend(other, start, length, share);120}121}122}123124pub fn subslice_extend_each_repeated(125&mut self,126other: &Series,127mut start: usize,128mut length: usize,129repeats: usize,130share: ShareStrategy,131) {132if length == 0 || repeats == 0 || other.is_empty() {133return;134}135136for chunk in other.chunks() {137if start < chunk.len() {138let length_in_chunk = length.min(chunk.len() - start);139self.builder.subslice_extend_each_repeated(140&**chunk,141start,142length_in_chunk,143repeats,144share,145);146147start = 0;148length -= length_in_chunk;149if length == 0 {150break;151}152} else {153start -= chunk.len();154}155}156}157158/// Extends this builder with the contents of the given series at the given159/// indices. That is, `other[idxs[i]]` is appended to this builder in order,160/// for each i=0..idxs.len(). May panic if other does not match the dtype161/// of this builder, or if the other series is not rechunked.162///163/// # Safety164/// The indices must be in-bounds.165pub unsafe fn gather_extend(&mut self, other: &Series, idxs: &[IdxSize], share: ShareStrategy) {166let chunks = other.chunks();167assert!(chunks.len() == 1);168self.builder.gather_extend(&*chunks[0], idxs, share);169}170171pub fn opt_gather_extend(&mut self, other: &Series, idxs: &[IdxSize], share: ShareStrategy) {172let chunks = other.chunks();173assert!(chunks.len() == 1);174self.builder.opt_gather_extend(&*chunks[0], idxs, share);175}176177pub fn push_any_value(&mut self, value: AnyValue<'static>) {178// @PERF179self.extend(180&Scalar::new(self.dtype.clone(), value).into_series(PlSmallStr::EMPTY),181ShareStrategy::Always,182);183}184}185186187