Merge pull request #399 from influxdata/er/feat/row_ids

feat: implement methods for getting rows via predicate
pull/24376/head
Edd Robinson 2020-11-02 15:29:00 +00:00 committed by GitHub
commit 8303dd197b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 1214 additions and 221 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,5 @@
/// Possible comparison operators
#[derive(Debug)]
pub enum Operator {
Equal,
NotEqual,

View File

@ -193,6 +193,11 @@ impl RLE {
self.num_rows
}
/// Determine if NULL is encoded in the column.
pub fn contains_null(&self) -> bool {
self.contains_null
}
//
//
// ---- Methods for getting row ids from values.
@ -201,7 +206,7 @@ impl RLE {
/// Populates the provided destination container with the row ids satisfying
/// the provided predicate.
pub fn row_ids_filter(&self, value: String, op: cmp::Operator, dst: RowIDs) -> RowIDs {
pub fn row_ids_filter(&self, value: &str, op: cmp::Operator, dst: RowIDs) -> RowIDs {
match op {
cmp::Operator::Equal | cmp::Operator::NotEqual => self.row_ids_equal(value, op, dst),
cmp::Operator::LT | cmp::Operator::LTE | cmp::Operator::GT | cmp::Operator::GTE => {
@ -211,7 +216,7 @@ impl RLE {
}
// Finds row ids based on = or != operator.
fn row_ids_equal(&self, value: String, op: cmp::Operator, mut dst: RowIDs) -> RowIDs {
fn row_ids_equal(&self, value: &str, op: cmp::Operator, mut dst: RowIDs) -> RowIDs {
dst.clear();
let include = match op {
cmp::Operator::Equal => true,
@ -219,7 +224,7 @@ impl RLE {
_ => unreachable!("invalid operator"),
};
if let Some(encoded_id) = self.entry_index.get(&value) {
if let Some(encoded_id) = self.entry_index.get(value) {
let mut index: u32 = 0;
for (other_encoded_id, other_rl) in &self.run_lengths {
let start = index;
@ -249,11 +254,11 @@ impl RLE {
}
// Finds row ids based on <, <=, > or >= operator.
fn row_ids_cmp(&self, value: String, op: cmp::Operator, mut dst: RowIDs) -> RowIDs {
fn row_ids_cmp(&self, value: &str, op: cmp::Operator, mut dst: RowIDs) -> RowIDs {
dst.clear();
// happy path - the value exists in the column
if let Some(encoded_id) = self.entry_index.get(&value) {
if let Some(encoded_id) = self.entry_index.get(value) {
let cmp = match op {
cmp::Operator::GT => PartialOrd::gt,
cmp::Operator::GTE => PartialOrd::ge,
@ -280,9 +285,9 @@ impl RLE {
cmp::Operator::GT | cmp::Operator::GTE => {
// find the first decoded value that satisfies the predicate.
for (other, other_encoded_id) in &self.entry_index {
if other > &value {
if other.as_str() > value {
// change filter from either `x > value` or `x >= value` to `x >= other`
return self.row_ids_cmp(other.clone(), cmp::Operator::GTE, dst);
return self.row_ids_cmp(other, cmp::Operator::GTE, dst);
}
}
}
@ -290,9 +295,9 @@ impl RLE {
// find the first decoded value that satisfies the predicate.
// Note iteration is in reverse
for (other, other_encoded_id) in self.entry_index.iter().rev() {
if other < &value {
if other.as_str() < value {
// change filter from either `x < value` or `x <= value` to `x <= other`
return self.row_ids_cmp(other.clone(), cmp::Operator::LTE, dst);
return self.row_ids_cmp(other, cmp::Operator::LTE, dst);
}
}
}
@ -858,40 +863,20 @@ mod test {
drle.push_none(); // 9
drle.push_additional(Some("south".to_string()), 2); // 10, 11
let ids = drle.row_ids_filter(
"east".to_string(),
cmp::Operator::Equal,
RowIDs::Vector(vec![]),
);
let ids = drle.row_ids_filter(&"east", cmp::Operator::Equal, RowIDs::Vector(vec![]));
assert_eq!(ids, RowIDs::Vector(vec![0, 1, 2, 4, 5, 6, 7, 8]));
let ids = drle.row_ids_filter(
"south".to_string(),
cmp::Operator::Equal,
RowIDs::Vector(vec![]),
);
let ids = drle.row_ids_filter(&"south", cmp::Operator::Equal, RowIDs::Vector(vec![]));
assert_eq!(ids, RowIDs::Vector(vec![10, 11]));
let ids = drle.row_ids_filter(
"foo".to_string(),
cmp::Operator::Equal,
RowIDs::Vector(vec![]),
);
let ids = drle.row_ids_filter(&"foo", cmp::Operator::Equal, RowIDs::Vector(vec![]));
assert!(ids.is_empty());
// != some value not in the column should exclude the NULL value.
let ids = drle.row_ids_filter(
"foo".to_string(),
cmp::Operator::NotEqual,
RowIDs::Vector(vec![]),
);
let ids = drle.row_ids_filter(&"foo", cmp::Operator::NotEqual, RowIDs::Vector(vec![]));
assert_eq!(ids, RowIDs::Vector(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11]));
let ids = drle.row_ids_filter(
"east".to_string(),
cmp::Operator::NotEqual,
RowIDs::Vector(vec![]),
);
let ids = drle.row_ids_filter(&"east", cmp::Operator::NotEqual, RowIDs::Vector(vec![]));
assert_eq!(ids, RowIDs::Vector(vec![3, 10, 11]));
}
@ -901,11 +886,7 @@ mod test {
drle.push_additional(Some("east".to_string()), 2);
drle.push_additional(Some("west".to_string()), 1);
let ids = drle.row_ids_filter(
"abba".to_string(),
cmp::Operator::NotEqual,
RowIDs::Vector(vec![]),
);
let ids = drle.row_ids_filter(&"abba", cmp::Operator::NotEqual, RowIDs::Vector(vec![]));
assert_eq!(ids, RowIDs::Vector(vec![0, 1, 2]));
}
@ -921,43 +902,23 @@ mod test {
drle.push_none(); // 13
drle.push_additional(Some("west".to_string()), 5); // 14, 15, 16, 17, 18
let ids = drle.row_ids_filter(
"east".to_string(),
cmp::Operator::LTE,
RowIDs::Vector(vec![]),
);
let ids = drle.row_ids_filter(&"east", cmp::Operator::LTE, RowIDs::Vector(vec![]));
assert_eq!(ids, RowIDs::Vector(vec![0, 1, 2, 4, 5, 6, 7, 8]));
let ids = drle.row_ids_filter(
"east".to_string(),
cmp::Operator::LT,
RowIDs::Vector(vec![]),
);
let ids = drle.row_ids_filter(&"east", cmp::Operator::LT, RowIDs::Vector(vec![]));
assert!(ids.is_empty());
let ids = drle.row_ids_filter(
"north".to_string(),
cmp::Operator::GT,
RowIDs::Vector(vec![]),
);
let ids = drle.row_ids_filter(&"north", cmp::Operator::GT, RowIDs::Vector(vec![]));
assert_eq!(ids, RowIDs::Vector(vec![9, 10, 11, 14, 15, 16, 17, 18]));
let ids = drle.row_ids_filter(
"north".to_string(),
cmp::Operator::GTE,
RowIDs::Vector(vec![]),
);
let ids = drle.row_ids_filter(&"north", cmp::Operator::GTE, RowIDs::Vector(vec![]));
assert_eq!(
ids,
RowIDs::Vector(vec![3, 9, 10, 11, 12, 14, 15, 16, 17, 18])
);
// The encoding also supports comparisons on values that don't directly exist in the column.
let ids = drle.row_ids_filter(
"abba".to_string(),
cmp::Operator::GT,
RowIDs::Vector(vec![]),
);
let ids = drle.row_ids_filter(&"abba", cmp::Operator::GT, RowIDs::Vector(vec![]));
assert_eq!(
ids,
RowIDs::Vector(vec![
@ -965,45 +926,25 @@ mod test {
])
);
let ids = drle.row_ids_filter(
"east1".to_string(),
cmp::Operator::GT,
RowIDs::Vector(vec![]),
);
let ids = drle.row_ids_filter(&"east1", cmp::Operator::GT, RowIDs::Vector(vec![]));
assert_eq!(
ids,
RowIDs::Vector(vec![3, 9, 10, 11, 12, 14, 15, 16, 17, 18])
);
let ids = drle.row_ids_filter(
"east1".to_string(),
cmp::Operator::GTE,
RowIDs::Vector(vec![]),
);
let ids = drle.row_ids_filter(&"east1", cmp::Operator::GTE, RowIDs::Vector(vec![]));
assert_eq!(
ids,
RowIDs::Vector(vec![3, 9, 10, 11, 12, 14, 15, 16, 17, 18])
);
let ids = drle.row_ids_filter(
"east1".to_string(),
cmp::Operator::LTE,
RowIDs::Vector(vec![]),
);
let ids = drle.row_ids_filter(&"east1", cmp::Operator::LTE, RowIDs::Vector(vec![]));
assert_eq!(ids, RowIDs::Vector(vec![0, 1, 2, 4, 5, 6, 7, 8]));
let ids = drle.row_ids_filter(
"region".to_string(),
cmp::Operator::LT,
RowIDs::Vector(vec![]),
);
let ids = drle.row_ids_filter(&"region", cmp::Operator::LT, RowIDs::Vector(vec![]));
assert_eq!(ids, RowIDs::Vector(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 12]));
let ids = drle.row_ids_filter(
"zoo".to_string(),
cmp::Operator::LTE,
RowIDs::Vector(vec![]),
);
let ids = drle.row_ids_filter(&"zoo", cmp::Operator::LTE, RowIDs::Vector(vec![]));
assert_eq!(
ids,
RowIDs::Vector(vec![

View File

@ -17,9 +17,7 @@ use std::fmt::{Debug, Display};
use std::mem::size_of;
use std::ops::AddAssign;
use croaring::Bitmap;
use crate::column::cmp;
use crate::column::{cmp, RowIDs};
#[derive(Debug, Default)]
/// A Fixed encoding is one in which every value has a fixed width, and is
@ -32,7 +30,7 @@ use crate::column::cmp;
///
pub struct Fixed<T>
where
T: PartialOrd,
T: PartialOrd + std::fmt::Debug,
{
// backing data
values: Vec<T>,
@ -44,7 +42,7 @@ where
impl<T> std::fmt::Display for Fixed<T>
where
T: Display + PartialOrd + Copy,
T: std::fmt::Debug + Display + PartialOrd + Copy,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
@ -58,7 +56,7 @@ where
impl<T> Fixed<T>
where
T: PartialOrd + Copy,
T: std::fmt::Debug + PartialOrd + Copy,
{
pub fn num_rows(&self) -> u32 {
self.values.len() as u32
@ -264,23 +262,17 @@ where
//
//
/// Returns the set of row ids that satisfy a binary operator on a logical
/// value. Note, it is the caller's responsibility to ensure the value
/// provided can be correctly converted from the logical to physical
/// representation.
/// Returns the set of row ids that satisfy a binary operator on a physical
/// value.
///
/// Essentially, this supports `value {=, !=, >, >=, <, <=} x`.
pub fn row_ids_filter<U>(&self, value: U, op: cmp::Operator, bm: Bitmap) -> Bitmap
where
T: From<U>,
{
let physical_value = T::from(value);
pub fn row_ids_filter(&self, value: T, op: cmp::Operator, dst: RowIDs) -> RowIDs {
match op {
cmp::Operator::GT => self.row_ids_cmp_order_bm(&physical_value, PartialOrd::gt, bm),
cmp::Operator::GTE => self.row_ids_cmp_order_bm(&physical_value, PartialOrd::ge, bm),
cmp::Operator::LT => self.row_ids_cmp_order_bm(&physical_value, PartialOrd::lt, bm),
cmp::Operator::LTE => self.row_ids_cmp_order_bm(&physical_value, PartialOrd::le, bm),
_ => self.row_ids_equal_bm(&physical_value, op, bm),
cmp::Operator::GT => self.row_ids_cmp_order(&value, PartialOrd::gt, dst),
cmp::Operator::GTE => self.row_ids_cmp_order(&value, PartialOrd::ge, dst),
cmp::Operator::LT => self.row_ids_cmp_order(&value, PartialOrd::lt, dst),
cmp::Operator::LTE => self.row_ids_cmp_order(&value, PartialOrd::le, dst),
_ => self.row_ids_equal(&value, op, dst),
}
}
@ -298,8 +290,8 @@ where
// Handles finding all rows that match the provided operator on `value`.
// For performance reasons ranges of matching values are collected up and
// added in bulk to the bitmap.
fn row_ids_equal_bm(&self, value: &T, op: cmp::Operator, mut bm: Bitmap) -> Bitmap {
bm.clear();
fn row_ids_equal(&self, value: &T, op: cmp::Operator, mut dst: RowIDs) -> RowIDs {
dst.clear();
let desired;
if let cmp::Operator::Equal = op {
@ -314,8 +306,8 @@ where
let cmp_result = next == value;
if cmp_result != desired && found {
let (min, max) = (i as u64 - count as u64, i as u64);
bm.add_range(min..max);
let (min, max) = (i as u32 - count as u32, i as u32);
dst.add_range(min, max);
found = false;
count = 0;
continue;
@ -332,12 +324,12 @@ where
// add any remaining range.
if found {
let (min, max) = (
(self.values.len()) as u64 - count as u64,
(self.values.len()) as u64,
(self.values.len()) as u32 - count as u32,
(self.values.len()) as u32,
);
bm.add_range(min..max);
dst.add_range(min, max);
}
bm
dst
}
// Handles finding all rows that match the provided operator on `value`.
@ -346,11 +338,11 @@ where
//
// `op` is a tuple of comparisons where at least one of them must be
// satisfied to satisfy the overall operator.
fn row_ids_cmp_order_bm<F>(&self, value: &T, op: F, mut bm: Bitmap) -> Bitmap
fn row_ids_cmp_order<F>(&self, value: &T, op: F, mut dst: RowIDs) -> RowIDs
where
F: Fn(&T, &T) -> bool,
{
bm.clear();
dst.clear();
let mut found = false;
let mut count = 0;
@ -358,8 +350,8 @@ where
let cmp_result = op(next, value);
if !cmp_result && found {
let (min, max) = (i as u64 - count as u64, i as u64);
bm.add_range(min..max);
let (min, max) = (i as u32 - count as u32, i as u32);
dst.add_range(min, max);
found = false;
count = 0;
continue;
@ -376,37 +368,28 @@ where
// add any remaining range.
if found {
let (min, max) = (
(self.values.len()) as u64 - count as u64,
(self.values.len()) as u64,
(self.values.len()) as u32 - count as u32,
(self.values.len()) as u32,
);
bm.add_range(min..max);
dst.add_range(min, max);
}
bm
dst
}
/// Returns the set of row ids that satisfy a pair of binary operators
/// against two values of the same logical type.
///
/// Note, it is the caller's responsibility to provide values that can
/// safely be converted from the logical type `U` to the physical type `T`.
/// against two values of the same physical type.
///
/// This method is a special case optimisation for common cases where one
/// wishes to do the equivalent of WHERE x > y AND x <= y` for example.
///
/// Essentially, this supports:
/// `x {>, >=, <, <=} value1 AND x {>, >=, <, <=} value2`.
pub fn row_ids_filter_range<U>(
pub fn row_ids_filter_range(
&self,
left: (U, cmp::Operator),
right: (U, cmp::Operator),
bm: Bitmap,
) -> Bitmap
where
T: From<U>,
{
let left_physical = T::from(left.0);
let right_physical = T::from(right.0);
left: (T, cmp::Operator),
right: (T, cmp::Operator),
dst: RowIDs,
) -> RowIDs {
match (&left.1, &right.1) {
(cmp::Operator::GT, cmp::Operator::LT)
| (cmp::Operator::GT, cmp::Operator::LTE)
@ -415,10 +398,10 @@ where
| (cmp::Operator::LT, cmp::Operator::GT)
| (cmp::Operator::LT, cmp::Operator::GTE)
| (cmp::Operator::LTE, cmp::Operator::GT)
| (cmp::Operator::LTE, cmp::Operator::GTE) => self.row_ids_cmp_range_order_bm(
(&left_physical, Self::ord_from_op(&left.1)),
(&right_physical, Self::ord_from_op(&right.1)),
bm,
| (cmp::Operator::LTE, cmp::Operator::GTE) => self.row_ids_cmp_range_order(
(&left.0, Self::ord_from_op(&left.1)),
(&right.0, Self::ord_from_op(&right.1)),
dst,
),
(_, _) => panic!("unsupported operators provided"),
@ -442,13 +425,13 @@ where
// For performance reasons ranges of matching values are collected up and
// added in bulk to the bitmap.
//
fn row_ids_cmp_range_order_bm(
fn row_ids_cmp_range_order(
&self,
left: (&T, (std::cmp::Ordering, std::cmp::Ordering)),
right: (&T, (std::cmp::Ordering, std::cmp::Ordering)),
mut bm: Bitmap,
) -> Bitmap {
bm.clear();
mut dst: RowIDs,
) -> RowIDs {
dst.clear();
let left_op = left.1;
let right_op = right.1;
@ -462,11 +445,11 @@ where
let left_result_no =
left_cmp_result != Some(left_op.0) && left_cmp_result != Some(left_op.1);
let right_result_no =
right_cmp_result != Some(right_op.0) && left_cmp_result != Some(right_op.1);
right_cmp_result != Some(right_op.0) && right_cmp_result != Some(right_op.1);
if (left_result_no || right_result_no) && found {
let (min, max) = (i as u64 - count as u64, i as u64);
bm.add_range(min..max);
let (min, max) = (i as u32 - count as u32, i as u32);
dst.add_range(min, max);
found = false;
count = 0;
continue;
@ -483,12 +466,12 @@ where
// add any remaining range.
if found {
let (min, max) = (
(self.values.len()) as u64 - count as u64,
(self.values.len()) as u64,
(self.values.len()) as u32 - count as u32,
(self.values.len()) as u32,
);
bm.add_range(min..max);
dst.add_range(min, max);
}
bm
dst
}
}
@ -660,22 +643,45 @@ mod test {
// assert!(v.max::<f64>(&[0, 1, 2, 3]).is_nan());
}
#[test]
fn ord_from_op() {
assert_eq!(
Fixed::<i64>::ord_from_op(&cmp::Operator::LT),
(Ordering::Less, Ordering::Less)
);
assert_eq!(
Fixed::<i64>::ord_from_op(&cmp::Operator::GT),
(Ordering::Greater, Ordering::Greater)
);
assert_eq!(
Fixed::<i64>::ord_from_op(&cmp::Operator::LTE),
(Ordering::Less, Ordering::Equal)
);
assert_eq!(
Fixed::<i64>::ord_from_op(&cmp::Operator::GTE),
(Ordering::Greater, Ordering::Equal)
);
}
#[test]
fn row_ids_filter_eq() {
let mut v: Fixed<i64> = Fixed::default();
v.values = vec![100, 101, 100, 102, 1000, 300, 2030, 3, 101, 4, 5, 21, 100];
let bm = v.row_ids_filter(100, Operator::Equal, Bitmap::create());
assert_eq!(bm.to_vec(), vec![0, 2, 12]);
let dst = v.row_ids_filter(100, Operator::Equal, RowIDs::new_vector());
assert_eq!(dst.unwrap_vector(), &vec![0, 2, 12]);
let bm = v.row_ids_filter(101, Operator::Equal, Bitmap::create());
assert_eq!(bm.to_vec(), vec![1, 8]);
let dst = v.row_ids_filter(101, Operator::Equal, RowIDs::new_vector());
assert_eq!(dst.unwrap_vector(), &vec![1, 8]);
let bm = v.row_ids_filter(2030, Operator::Equal, Bitmap::create());
assert_eq!(bm.to_vec(), vec![6]);
let dst = v.row_ids_filter(2030, Operator::Equal, RowIDs::new_vector());
assert_eq!(dst.unwrap_vector(), &vec![6]);
let bm = v.row_ids_filter(194, Operator::Equal, Bitmap::create());
assert!(bm.is_empty());
let dst = v.row_ids_filter(194, Operator::Equal, RowIDs::new_vector());
assert!(dst.is_empty());
}
#[test]
@ -683,17 +689,23 @@ mod test {
let mut v: Fixed<i64> = Fixed::default();
v.values = vec![100, 101, 100, 102, 1000, 300, 2030, 3, 101, 4, 5, 21, 100];
let bm = v.row_ids_filter(100, Operator::NotEqual, Bitmap::create());
assert_eq!(bm.to_vec(), vec![1, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
let dst = v.row_ids_filter(100, Operator::NotEqual, RowIDs::new_vector());
assert_eq!(dst.unwrap_vector(), &vec![1, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
let bm = v.row_ids_filter(101, Operator::NotEqual, Bitmap::create());
assert_eq!(bm.to_vec(), vec![0, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12]);
let dst = v.row_ids_filter(101, Operator::NotEqual, RowIDs::new_vector());
assert_eq!(
dst.unwrap_vector(),
&vec![0, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12]
);
let bm = v.row_ids_filter(2030, Operator::NotEqual, Bitmap::create());
assert_eq!(bm.to_vec(), vec![0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12]);
let dst = v.row_ids_filter(2030, Operator::NotEqual, RowIDs::new_vector());
assert_eq!(
dst.unwrap_vector(),
&vec![0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12]
);
let bm = v.row_ids_filter(194, Operator::NotEqual, Bitmap::create());
assert_eq!(bm.to_vec(), (0..13).collect::<Vec<u32>>());
let dst = v.row_ids_filter(194, Operator::NotEqual, RowIDs::new_vector());
assert_eq!(dst.unwrap_vector(), &(0..13).collect::<Vec<u32>>());
}
#[test]
@ -701,11 +713,11 @@ mod test {
let mut v: Fixed<i64> = Fixed::default();
v.values = vec![100, 101, 100, 102, 1000, 300, 2030, 3, 101, 4, 5, 21, 100];
let bm = v.row_ids_filter(100, Operator::LT, Bitmap::create());
assert_eq!(bm.to_vec(), vec![7, 9, 10, 11]);
let dst = v.row_ids_filter(100, Operator::LT, RowIDs::new_vector());
assert_eq!(dst.unwrap_vector(), &vec![7, 9, 10, 11]);
let bm = v.row_ids_filter(3, Operator::LT, Bitmap::create());
assert_eq!(bm.to_vec(), Vec::<u32>::new());
let dst = v.row_ids_filter(3, Operator::LT, RowIDs::new_vector());
assert_eq!(dst.unwrap_vector(), &Vec::<u32>::new());
}
#[test]
@ -713,11 +725,11 @@ mod test {
let mut v: Fixed<i64> = Fixed::default();
v.values = vec![100, 101, 100, 102, 1000, 300, 2030, 3, 101, 4, 5, 21, 100];
let bm = v.row_ids_filter(100, Operator::LTE, Bitmap::create());
assert_eq!(bm.to_vec(), vec![0, 2, 7, 9, 10, 11, 12]);
let dst = v.row_ids_filter(100, Operator::LTE, RowIDs::new_vector());
assert_eq!(dst.unwrap_vector(), &vec![0, 2, 7, 9, 10, 11, 12]);
let bm = v.row_ids_filter(2, Operator::LTE, Bitmap::create());
assert!(bm.is_empty());
let dst = v.row_ids_filter(2, Operator::LTE, RowIDs::new_vector());
assert!(dst.is_empty());
}
#[test]
@ -725,11 +737,11 @@ mod test {
let mut v: Fixed<i64> = Fixed::default();
v.values = vec![100, 101, 100, 102, 1000, 300, 2030, 3, 101, 4, 5, 21, 100];
let bm = v.row_ids_filter(100, Operator::GT, Bitmap::create());
assert_eq!(bm.to_vec(), vec![1, 3, 4, 5, 6, 8]);
let dst = v.row_ids_filter(100, Operator::GT, RowIDs::new_vector());
assert_eq!(dst.unwrap_vector(), &vec![1, 3, 4, 5, 6, 8]);
let bm = v.row_ids_filter(2030, Operator::GT, Bitmap::create());
assert!(bm.is_empty());
let dst = v.row_ids_filter(2030, Operator::GT, RowIDs::new_vector());
assert!(dst.is_empty());
}
#[test]
@ -737,11 +749,11 @@ mod test {
let mut v: Fixed<i64> = Fixed::default();
v.values = vec![100, 101, 100, 102, 1000, 300, 2030, 3, 101, 4, 5, 21, 100];
let bm = v.row_ids_filter(100, Operator::GTE, Bitmap::create());
assert_eq!(bm.to_vec(), vec![0, 1, 2, 3, 4, 5, 6, 8, 12]);
let dst = v.row_ids_filter(100, Operator::GTE, RowIDs::new_vector());
assert_eq!(dst.unwrap_vector(), &vec![0, 1, 2, 3, 4, 5, 6, 8, 12]);
let bm = v.row_ids_filter(2031, Operator::GTE, Bitmap::create());
assert!(bm.is_empty());
let dst = v.row_ids_filter(2031, Operator::GTE, RowIDs::new_vector());
assert!(dst.is_empty());
}
#[test]
@ -749,24 +761,48 @@ mod test {
let mut v: Fixed<i64> = Fixed::default();
v.values = vec![100, 101, 100, 102, 1000, 300, 2030, 3, 101, 4, 5, 21, 100];
let bm =
v.row_ids_filter_range((100, Operator::GTE), (240, Operator::LT), Bitmap::create());
assert_eq!(bm.to_vec(), vec![0, 1, 2, 3, 8, 12]);
let dst = v.row_ids_filter_range(
(100, Operator::GTE),
(240, Operator::LT),
RowIDs::new_vector(),
);
assert_eq!(dst.unwrap_vector(), &vec![0, 1, 2, 3, 8, 12]);
let bm = v.row_ids_filter_range((100, Operator::GT), (240, Operator::LT), Bitmap::create());
assert_eq!(bm.to_vec(), vec![1, 3, 8]);
let dst = v.row_ids_filter_range(
(100, Operator::GT),
(240, Operator::LT),
RowIDs::new_vector(),
);
assert_eq!(dst.unwrap_vector(), &vec![1, 3, 8]);
let bm = v.row_ids_filter_range((10, Operator::LT), (-100, Operator::GT), Bitmap::create());
assert_eq!(bm.to_vec(), vec![7, 9, 10]);
let dst = v.row_ids_filter_range(
(10, Operator::LT),
(-100, Operator::GT),
RowIDs::new_vector(),
);
assert_eq!(dst.unwrap_vector(), &vec![7, 9, 10]);
let bm = v.row_ids_filter_range((21, Operator::GTE), (21, Operator::LTE), Bitmap::create());
assert_eq!(bm.to_vec(), vec![11]);
let dst = v.row_ids_filter_range(
(21, Operator::GTE),
(21, Operator::LTE),
RowIDs::new_vector(),
);
assert_eq!(dst.unwrap_vector(), &vec![11]);
let bm = v.row_ids_filter_range(
let dst = v.row_ids_filter_range(
(10000, Operator::LTE),
(3999, Operator::GT),
Bitmap::create(),
RowIDs::new_bitmap(),
);
assert!(bm.is_empty());
assert!(dst.is_empty());
let mut v: Fixed<i64> = Fixed::default();
v.values = vec![100, 200, 300, 2, 200, 22, 30];
let dst = v.row_ids_filter_range(
(200, Operator::GTE),
(300, Operator::LTE),
RowIDs::new_vector(),
);
assert_eq!(dst.unwrap_vector(), &vec![1, 2, 4]);
}
}

View File

@ -63,6 +63,10 @@ where
self.arr.is_empty()
}
pub fn contains_null(&self) -> bool {
self.arr.null_count() == 0
}
/// Returns the total size in bytes of the encoded data. Note, this method
/// is really an "accurate" estimation. It doesn't include for example the
/// size of the `Plain` struct receiver.
@ -445,7 +449,7 @@ where
let left_result_no =
left_cmp_result != Some(left_op.0) && left_cmp_result != Some(left_op.1);
let right_result_no =
right_cmp_result != Some(right_op.0) && left_cmp_result != Some(right_op.1);
right_cmp_result != Some(right_op.0) && right_cmp_result != Some(right_op.1);
if (self.arr.is_null(i) || left_result_no || right_result_no) && found {
let (min, max) = (i as u64 - count as u64, i as u64);
@ -766,7 +770,7 @@ mod test {
#[test]
fn row_ids_filter_range() {
let v = super::FixedNull::<Int64Type>::from(
let v = FixedNull::<Int64Type>::from(
vec![
Some(100),
Some(101),
@ -811,5 +815,21 @@ mod test {
Bitmap::create(),
);
assert_eq!(bm.to_vec(), Vec::<u32>::new());
let v = FixedNull::<Int64Type>::from(
vec![
Some(100),
Some(200),
Some(300),
Some(2),
Some(200),
Some(22),
Some(30),
]
.as_slice(),
);
let bm =
v.row_ids_filter_range((200, Operator::GTE), (300, Operator::LTE), Bitmap::create());
assert_eq!(bm.to_vec(), vec![1, 2, 4]);
}
}