Skip to content

Commit

Permalink
rewrite null_count() == 0
Browse files Browse the repository at this point in the history
  • Loading branch information
ritchie46 committed Nov 4, 2021
1 parent 2d7703b commit fa13883
Show file tree
Hide file tree
Showing 27 changed files with 99 additions and 79 deletions.
2 changes: 1 addition & 1 deletion polars/polars-arrow/src/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,4 +178,4 @@ pub trait PolarsArray: Array {
}
}

impl<A: Array> PolarsArray for A {}
impl<A: Array + ?Sized> PolarsArray for A {}
3 changes: 2 additions & 1 deletion polars/polars-arrow/src/kernels/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use arrow::array::*;
use arrow::buffer::MutableBuffer;
use arrow::{datatypes::DataType, types::NativeType};
use std::ops::BitOr;
use crate::prelude::PolarsArray;

/// Set values in a primitive array where the primitive array has null values.
/// this is faster because we don't have to invert and combine bitmaps
Expand All @@ -13,7 +14,7 @@ where
T: NativeType,
{
let values = array.values();
if array.null_count() == 0 {
if !array.has_validity() {
return array.clone();
}

Expand Down
8 changes: 4 additions & 4 deletions polars/polars-arrow/src/kernels/take.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ pub unsafe fn take_utf8_unchecked(
let mut values_buf = AlignedVec::<u8>::with_capacity(values_capacity);

// both 0 nulls
if arr.null_count() == 0 && indices.null_count() == 0 {
if !arr.has_validity() && !indices.has_validity() {
offset_typed
.iter_mut()
.skip(1)
Expand All @@ -377,7 +377,7 @@ pub unsafe fn take_utf8_unchecked(
values_buf.extend_from_slice(s.as_bytes())
});
validity = None;
} else if arr.null_count() == 0 {
} else if !arr.has_validity() {
offset_typed
.iter_mut()
.skip(1)
Expand All @@ -402,7 +402,7 @@ pub unsafe fn take_utf8_unchecked(
let mut builder = MutableUtf8Array::with_capacities(data_len, length_so_far as usize);
let validity_arr = arr.validity().expect("should have nulls");

if indices.null_count() == 0 {
if !indices.has_validity() {
(0..data_len).for_each(|idx| {
let index = indices.value_unchecked(idx) as usize;
builder.push(if validity_arr.get_bit_unchecked(index) {
Expand Down Expand Up @@ -469,7 +469,7 @@ pub unsafe fn take_value_indices_from_list(

let indices_values = indices.values();

if indices.null_count() == 0 {
if !indices.has_validity() {
for i in 0..indices.len() {
let idx = *indices_values.get_unchecked(i) as usize;
let start = *offsets.get_unchecked(idx);
Expand Down
3 changes: 2 additions & 1 deletion polars/polars-core/src/chunked_array/builder/list.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::*;
use polars_arrow::prelude::PolarsArray;

pub trait ListBuilderTrait {
fn append_opt_series(&mut self, opt_s: Option<&Series>);
Expand Down Expand Up @@ -130,7 +131,7 @@ where
arrays.iter().for_each(|x| {
let arr = x.as_any().downcast_ref::<PrimitiveArray<T>>().unwrap();

if arr.null_count() == 0 {
if !arr.has_validity() {
values.extend_from_slice(arr.values().as_slice())
} else {
// Safety:
Expand Down
2 changes: 1 addition & 1 deletion polars/polars-core/src/chunked_array/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ impl ChunkCast for CategoricalChunked {

let f = |idx: u32| mapping.get(idx);

if self.null_count() == 0 {
if !self.has_validity() {
self.into_no_null_iter()
.for_each(|idx| builder.append_value(f(idx)));
} else {
Expand Down
4 changes: 2 additions & 2 deletions polars/polars-core/src/chunked_array/iterator/par/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ macro_rules! impl_into_par_iter {
let chunks = self.downcast_iter();
match chunks.len() {
1 => {
if self.null_count() == 0 {
if !self.has_validity() {
$dispatcher::SingleChunk(
<$single_chunk_return_option>::new(self),
)
Expand All @@ -568,7 +568,7 @@ macro_rules! impl_into_par_iter {
}
}
_ => {
if self.null_count() == 0 {
if !self.has_validity() {
$dispatcher::ManyChunk(
<$many_chunk_return_option>::new(self),
)
Expand Down
4 changes: 2 additions & 2 deletions polars/polars-core/src/chunked_array/iterator/par/numeric.rs
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,7 @@ where
let chunks = self.downcast_iter();
match chunks.len() {
1 => {
if self.null_count() == 0 {
if !self.has_validity() {
NumParIterDispatcher::SingleChunk(NumParIterSingleChunkReturnOption::new(self))
} else {
NumParIterDispatcher::SingleChunkNullCheck(
Expand All @@ -644,7 +644,7 @@ where
}
}
_ => {
if self.null_count() == 0 {
if !self.has_validity() {
NumParIterDispatcher::ManyChunk(NumParIterManyChunkReturnOption::new(self))
} else {
NumParIterDispatcher::ManyChunkNullCheck(
Expand Down
8 changes: 4 additions & 4 deletions polars/polars-core/src/chunked_array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ impl<T> ChunkedArray<T> {

/// Returns true if contains a single chunk and has no null values
pub fn is_optimal_aligned(&self) -> bool {
self.chunks.len() == 1 && self.null_count() == 0
self.chunks.len() == 1 && !self.has_validity()
}

/// Count the null values.
Expand Down Expand Up @@ -378,7 +378,7 @@ impl<T> ChunkedArray<T> {

/// Get a mask of the null values.
pub fn is_null(&self) -> BooleanChunked {
if self.null_count() == 0 {
if !self.has_validity() {
return BooleanChunked::full("is_null", false, self.len());
}
let chunks = self
Expand All @@ -397,7 +397,7 @@ impl<T> ChunkedArray<T> {

/// Get a mask of the valid values.
pub fn is_not_null(&self) -> BooleanChunked {
if self.null_count() == 0 {
if !self.has_validity() {
return BooleanChunked::full("is_not_null", true, self.len());
}
let chunks = self
Expand Down Expand Up @@ -579,7 +579,7 @@ where
{
/// Contiguous slice
pub fn cont_slice(&self) -> Result<&[T::Native]> {
if self.chunks.len() == 1 && self.chunks[0].null_count() == 0 {
if self.chunks.len() == 1 && !self.chunks[0].has_validity() {
Ok(self.downcast_iter().next().map(|arr| arr.values()).unwrap())
} else {
Err(PolarsError::NoSlice)
Expand Down
11 changes: 6 additions & 5 deletions polars/polars-core/src/chunked_array/ops/apply.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ use crate::utils::{CustomIterTools, NoNull};
use arrow::array::{Array, ArrayRef, BooleanArray, PrimitiveArray};
use std::borrow::Cow;
use std::convert::TryFrom;
use polars_arrow::array::PolarsArray;

macro_rules! try_apply {
($self:expr, $f:expr) => {{
if $self.null_count() == 0 {
if !$self.has_validity() {
$self.into_no_null_iter().map($f).collect()
} else {
$self
Expand All @@ -20,7 +21,7 @@ macro_rules! try_apply {

macro_rules! apply {
($self:expr, $f:expr) => {{
if $self.null_count() == 0 {
if !$self.has_validity() {
$self.into_no_null_iter().map($f).collect_trusted()
} else {
$self
Expand All @@ -33,7 +34,7 @@ macro_rules! apply {

macro_rules! apply_enumerate {
($self:expr, $f:expr) => {{
if $self.null_count() == 0 {
if !$self.has_validity() {
$self
.into_no_null_iter()
.enumerate()
Expand Down Expand Up @@ -77,7 +78,7 @@ where
let chunks = self
.downcast_iter()
.map(|array| {
let values = if array.null_count() == 0 {
let values = if !array.has_validity() {
let values = array.values().iter().map(|&v| f(Some(v)));
AlignedVec::<_>::from_trusted_len_iter(values)
} else {
Expand Down Expand Up @@ -144,7 +145,7 @@ where
where
F: Fn((usize, T::Native)) -> T::Native + Copy,
{
if self.null_count() == 0 {
if !self.has_validity() {
let ca: NoNull<_> = self
.into_no_null_iter()
.enumerate()
Expand Down
2 changes: 1 addition & 1 deletion polars/polars-core/src/chunked_array/ops/chunkops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ where

// todo! use iterators once implemented
// no_null path
if self.null_count() == 0 {
if !self.has_validity() {
for arr in chunks {
for idx in 0..arr.len() {
builder.append_value(arr.value(idx).clone())
Expand Down
4 changes: 2 additions & 2 deletions polars/polars-core/src/chunked_array/ops/compare_inner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ where
if self.chunks.len() == 1 {
let arr = chunks.next().unwrap();

if self.null_count() == 0 {
if !self.has_validity() {
let t = NumTakeRandomCont {
slice: arr.values(),
};
Expand Down Expand Up @@ -213,7 +213,7 @@ where
if self.chunks.len() == 1 {
let arr = chunks.next().unwrap();

if self.null_count() == 0 {
if !self.has_validity() {
let t = NumTakeRandomCont {
slice: arr.values(),
};
Expand Down
6 changes: 3 additions & 3 deletions polars/polars-core/src/chunked_array/ops/fill_null.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ where
{
fn fill_null(&self, strategy: FillNullStrategy) -> Result<Self> {
// nothing to fill
if self.null_count() == 0 {
if !self.has_validity() {
return Ok(self.clone());
}
let mut ca = match strategy {
Expand Down Expand Up @@ -126,7 +126,7 @@ where
impl ChunkFillNull for BooleanChunked {
fn fill_null(&self, strategy: FillNullStrategy) -> Result<Self> {
// nothing to fill
if self.null_count() == 0 {
if !self.has_validity() {
return Ok(self.clone());
}
match strategy {
Expand Down Expand Up @@ -171,7 +171,7 @@ impl ChunkFillNullValue<bool> for BooleanChunked {
impl ChunkFillNull for Utf8Chunked {
fn fill_null(&self, strategy: FillNullStrategy) -> Result<Self> {
// nothing to fill
if self.null_count() == 0 {
if !self.has_validity() {
return Ok(self.clone());
}
match strategy {
Expand Down
2 changes: 1 addition & 1 deletion polars/polars-core/src/chunked_array/ops/interpolate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ where
fn interpolate(&self) -> Self {
// This implementation differs from pandas as that boundary None's are not removed
// this prevents a lot of errors due to expressions leading to different lengths
if self.null_count() == 0 || self.null_count() == self.len() {
if !self.has_validity() || self.null_count() == self.len() {
return self.clone();
}

Expand Down
2 changes: 1 addition & 1 deletion polars/polars-core/src/chunked_array/ops/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ where
idx: I,
value: Option<T::Native>,
) -> Result<Self> {
if self.null_count() == 0 {
if !self.has_validity() {
if let Some(value) = value {
// fast path uses kernel
if self.chunks.len() == 1 {
Expand Down
4 changes: 2 additions & 2 deletions polars/polars-core/src/chunked_array/ops/sort.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ where
T: PolarsNumericType,
{
fn sort(&self, reverse: bool) -> ChunkedArray<T> {
if self.null_count() == 0 {
if !self.has_validity() {
let mut vals = memcpy_values(self);

sort_branch(vals.as_mut_slice(), reverse, order_default, order_reverse);
Expand Down Expand Up @@ -173,7 +173,7 @@ where
}

fn argsort(&self, reverse: bool) -> UInt32Chunked {
let ca: NoNull<UInt32Chunked> = if self.null_count() == 0 {
let ca: NoNull<UInt32Chunked> = if !self.has_validity() {
let mut vals = Vec::with_capacity(self.len());
let mut count: u32 = 0;
self.downcast_iter().for_each(|arr| {
Expand Down
12 changes: 7 additions & 5 deletions polars/polars-core/src/chunked_array/ops/take/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ use crate::utils::NoNull;

pub use take_random::*;
pub use traits::*;
use polars_arrow::array::PolarsArray;

mod take_every;
pub(crate) mod take_random;
pub(crate) mod take_single;
Expand Down Expand Up @@ -81,7 +83,7 @@ where
(_, 1) => take_primitive_unchecked::<T::Native>(chunks.next().unwrap(), array)
as ArrayRef,
_ => {
return if array.null_count() == 0 {
return if !array.has_validity() {
let iter = array.values().iter().map(|i| *i as usize);
let mut ca = take_primitive_iter_n_chunks(self, iter);
ca.rename(self.name());
Expand Down Expand Up @@ -172,7 +174,7 @@ impl ChunkTake for BooleanChunked {
let array = match self.chunks.len() {
1 => take::take(chunks.next().unwrap(), array).unwrap().into(),
_ => {
return if array.null_count() == 0 {
return if !array.has_validity() {
let iter = array.values().iter().map(|i| *i as usize);
let mut ca: BooleanChunked = take_iter_n_chunks!(self, iter);
ca.rename(self.name());
Expand Down Expand Up @@ -256,7 +258,7 @@ impl ChunkTake for Utf8Chunked {
let array = match self.chunks.len() {
1 => take_utf8_unchecked(chunks.next().unwrap(), array) as ArrayRef,
_ => {
return if array.null_count() == 0 {
return if !array.has_validity() {
let iter = array.values().iter().map(|i| *i as usize);
let mut ca: Utf8Chunked = take_iter_n_chunks_unchecked!(self, iter);
ca.rename(self.name());
Expand Down Expand Up @@ -334,7 +336,7 @@ impl ChunkTake for ListChunked {
let array = match self.chunks.len() {
1 => Arc::new(take_list_unchecked(chunks.next().unwrap(), array)) as ArrayRef,
_ => {
return if array.null_count() == 0 {
return if !array.has_validity() {
let iter = array.values().iter().map(|i| *i as usize);
let mut ca: ListChunked = take_iter_n_chunks_unchecked!(self, iter);
ca.rename(self.name());
Expand Down Expand Up @@ -435,7 +437,7 @@ impl<T: PolarsObject> ChunkTake for ObjectChunked<T> {
ca
}
_ => {
return if array.null_count() == 0 {
return if !array.has_validity() {
let iter = array.values().iter().map(|i| *i as usize);

let taker = self.take_rand();
Expand Down
8 changes: 4 additions & 4 deletions polars/polars-core/src/chunked_array/ops/take/take_every.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ where
T: PolarsNumericType,
{
fn take_every(&self, n: usize) -> ChunkedArray<T> {
if self.null_count() == 0 {
if !self.has_validity() {
let a: NoNull<_> = self.into_no_null_iter().step_by(n).collect();
a.into_inner()
} else {
Expand All @@ -19,7 +19,7 @@ where

impl ChunkTakeEvery<BooleanType> for BooleanChunked {
fn take_every(&self, n: usize) -> BooleanChunked {
if self.null_count() == 0 {
if !self.has_validity() {
self.into_no_null_iter().step_by(n).collect()
} else {
self.into_iter().step_by(n).collect()
Expand All @@ -29,7 +29,7 @@ impl ChunkTakeEvery<BooleanType> for BooleanChunked {

impl ChunkTakeEvery<Utf8Type> for Utf8Chunked {
fn take_every(&self, n: usize) -> Utf8Chunked {
if self.null_count() == 0 {
if !self.has_validity() {
self.into_no_null_iter().step_by(n).collect()
} else {
self.into_iter().step_by(n).collect()
Expand All @@ -39,7 +39,7 @@ impl ChunkTakeEvery<Utf8Type> for Utf8Chunked {

impl ChunkTakeEvery<ListType> for ListChunked {
fn take_every(&self, n: usize) -> ListChunked {
if self.null_count() == 0 {
if !self.has_validity() {
self.into_no_null_iter().step_by(n).collect()
} else {
self.into_iter().step_by(n).collect()
Expand Down

0 comments on commit fa13883

Please sign in to comment.