fn row_ids_from_predicate(&self, predicate: &Predicate) -> RowIDsOption {
        // TODO(edd): perf - potentially pool this so we can re-use it once rows
        // have been materialised and it's no longer needed. Initialise a bitmap
        // RowIDs because it's like that set operations will be necessary.
        let mut result_row_ids = RowIDs::new_bitmap();

        // TODO(edd): perf - pool the dst buffer so we can re-use it across
        // subsequent calls to `row_ids_from_predicates`. Right now this buffer
        // will be re-used across all columns in the `RowGroup` but not re-used
        // for subsequent calls _to_ the `RowGroup`.
        let mut dst = RowIDs::new_bitmap();

        let mut predicate = Cow::Borrowed(predicate);

        // If there is a time-range in the predicate (two time expressions),
        // then execute an optimised version that will use a range based
        // filter on the time column, effectively avoiding a scan and
        // intersection.
        if predicate.contains_time_range() {
            predicate = predicate.to_owned(); // We need to modify the predicate

            let time_range = predicate
                .to_mut()
                .remove_expr_by_column_name(TIME_COLUMN_NAME);

            // removes time expression from predicate
            let time_pred_row_ids = self.row_ids_from_time_range(&time_range, dst);
            match time_pred_row_ids {
                // No matching rows based on time range
                RowIDsOption::None(_) => return time_pred_row_ids,

                // all rows match - continue to apply other predicates
                RowIDsOption::All(_dst) => {
                    dst = _dst; // hand buffer back
                }

                // some rows match - continue to apply predicates
                RowIDsOption::Some(row_ids) => {
                    // fill the result row id set with the matching rows from
                    // the time column.
                    result_row_ids.union(&row_ids);
                    dst = row_ids // hand buffer back
                }
            }
        }

        for expr in predicate.iter() {
            // N.B column should always exist because validation of predicates
            // should happen at the `Table` level.
            let (_, col) = self.column_name_and_column(expr.column());

            // Explanation of how this buffer pattern works. The idea is that
            // the buffer should be returned to the caller so it can be re-used
            // on other columns. Each call to `row_ids_filter` returns the
            // buffer back enabling it to be re-used.
            match col.row_ids_filter(&expr.op, &expr.literal_as_value(), dst) {
                // No rows will be returned for the `RowGroup` because this
                // column does not match any rows.
                RowIDsOption::None(_dst) => return RowIDsOption::None(_dst),

                // Intersect the row ids found at this column with all those
                // found on other column predicates.
                RowIDsOption::Some(row_ids) => {
                    if result_row_ids.is_empty() {
                        result_row_ids.union(&row_ids)
                    }
                    result_row_ids.intersect(&row_ids);
                    dst = row_ids; // hand buffer back
                }

                // This is basically a no-op because all rows match the
                // predicate on this column.
                RowIDsOption::All(_dst) => {
                    dst = _dst; // hand buffer back
                }
            }
        }

        if result_row_ids.is_empty() {
            // All rows matched all predicates because any predicates not
            // matching any rows would have resulted in an early return.
            return RowIDsOption::All(result_row_ids);
        }
        RowIDsOption::Some(result_row_ids)
    }
// Determines the set of row ids that satisfy the provided predicate.
Determines the set of row ids that satisfy the provided predicate.
Determines the set of row ids that satisfy the provided predicate .
fn row_ids_from_predicate(&self, predicate: &Predicate) -> RowIDsOption {
        // TODO(edd): perf - potentially pool this so we can re-use it once rows
        // have been materialised and it's no longer needed. Initialise a bitmap
        // RowIDs because it's like that set operations will be necessary.
        let mut result_row_ids = RowIDs::new_bitmap();
        // TODO(edd): perf - pool the dst buffer so we can re-use it across
        // subsequent calls to `row_ids_from_predicates`. Right now this buffer
        // will be re-used across all columns in the `RowGroup` but not re-used
        // for subsequent calls _to_ the `RowGroup`.
        let mut dst = RowIDs::new_bitmap();
        let mut predicate = Cow::Borrowed(predicate);
        // If there is a time-range in the predicate (two time expressions),
        // then execute an optimised version that will use a range based
        // filter on the time column, effectively avoiding a scan and
        // intersection.
        if predicate.contains_time_range() {
            predicate = predicate.to_owned(); // We need to modify the predicate
            let time_range = predicate
                .to_mut()
                .remove_expr_by_column_name(TIME_COLUMN_NAME);
            // removes time expression from predicate
            let time_pred_row_ids = self.row_ids_from_time_range(&time_range, dst);
            match time_pred_row_ids {
                // No matching rows based on time range
                RowIDsOption::None(_) => return time_pred_row_ids,
                // all rows match - continue to apply other predicates
                RowIDsOption::All(_dst) => {
                    dst = _dst; // hand buffer back
                }
                // some rows match - continue to apply predicates
                RowIDsOption::Some(row_ids) => {
                    // fill the result row id set with the matching rows from
                    // the time column.
                    result_row_ids.union(&row_ids);
                    dst = row_ids // hand buffer back
                }
            }
        }
        for expr in predicate.iter() {
            // N.B column should always exist because validation of predicates
            // should happen at the `Table` level.
            let (_, col) = self.column_name_and_column(expr.column());
            // Explanation of how this buffer pattern works. The idea is that
            // the buffer should be returned to the caller so it can be re-used
            // on other columns. Each call to `row_ids_filter` returns the
            // buffer back enabling it to be re-used.
            match col.row_ids_filter(&expr.op, &expr.literal_as_value(), dst) {
                // No rows will be returned for the `RowGroup` because this
                // column does not match any rows.
                RowIDsOption::None(_dst) => return RowIDsOption::None(_dst),
                // Intersect the row ids found at this column with all those
                // found on other column predicates.
                RowIDsOption::Some(row_ids) => {
                    if result_row_ids.is_empty() {
                        result_row_ids.union(&row_ids)
                    }
                    result_row_ids.intersect(&row_ids);
                    dst = row_ids; // hand buffer back
                }
                // This is basically a no-op because all rows match the
                // predicate on this column.
                RowIDsOption::All(_dst) => {
                    dst = _dst; // hand buffer back
                }
            }
        }
        if result_row_ids.is_empty() {
            // All rows matched all predicates because any predicates not
            // matching any rows would have resulted in an early return.
            return RowIDsOption::All(result_row_ids);
        }
        RowIDsOption::Some(result_row_ids)
    }
fn row_ids_from_predicate ( & self , predicate : & Predicate ) -> RowIDsOption { // TODO(edd): perf - potentially pool this so we can re-use it once rows // have been materialised and it's no longer needed. Initialise a bitmap // RowIDs because it's like that set operations will be necessary. let mut result_row_ids = RowIDs :: new_bitmap ( ) ; // TODO(edd): perf - pool the dst buffer so we can re-use it across // subsequent calls to `row_ids_from_predicates`. Right now this buffer // will be re-used across all columns in the `RowGroup` but not re-used // for subsequent calls _to_ the `RowGroup`. let mut dst = RowIDs :: new_bitmap ( ) ; let mut predicate = Cow :: Borrowed ( predicate ) ; // If there is a time-range in the predicate (two time expressions), // then execute an optimised version that will use a range based // filter on the time column, effectively avoiding a scan and // intersection. if predicate . contains_time_range ( ) { predicate = predicate . to_owned ( ) ; // We need to modify the predicate let time_range = predicate . to_mut ( ) . remove_expr_by_column_name ( TIME_COLUMN_NAME ) ; // removes time expression from predicate let time_pred_row_ids = self . row_ids_from_time_range ( & time_range , dst ) ; match time_pred_row_ids { // No matching rows based on time range RowIDsOption :: None ( _ ) => return time_pred_row_ids , // all rows match - continue to apply other predicates RowIDsOption :: All ( _dst ) => { dst = _dst ; // hand buffer back } // some rows match - continue to apply predicates RowIDsOption :: Some ( row_ids ) => { // fill the result row id set with the matching rows from // the time column. result_row_ids . union ( & row_ids ) ; dst = row_ids // hand buffer back } } } for expr in predicate . iter ( ) { // N.B column should always exist because validation of predicates // should happen at the `Table` level. let ( _ , col ) = self . column_name_and_column ( expr . column ( ) ) ; // Explanation of how this buffer pattern works. The idea is that // the buffer should be returned to the caller so it can be re-used // on other columns. Each call to `row_ids_filter` returns the // buffer back enabling it to be re-used. match col . row_ids_filter ( & expr . op , & expr . literal_as_value ( ) , dst ) { // No rows will be returned for the `RowGroup` because this // column does not match any rows. RowIDsOption :: None ( _dst ) => return RowIDsOption :: None ( _dst ) , // Intersect the row ids found at this column with all those // found on other column predicates. RowIDsOption :: Some ( row_ids ) => { if result_row_ids . is_empty ( ) { result_row_ids . union ( & row_ids ) } result_row_ids . intersect ( & row_ids ) ; dst = row_ids ; // hand buffer back } // This is basically a no-op because all rows match the // predicate on this column. RowIDsOption :: All ( _dst ) => { dst = _dst ; // hand buffer back } } } if result_row_ids . is_empty ( ) { // All rows matched all predicates because any predicates not // matching any rows would have resulted in an early return. return RowIDsOption :: All ( result_row_ids ) ; } RowIDsOption :: Some ( result_row_ids ) }
Determines the set of row ids that satisfy the provided predicate.
Determines the set of row ids that satisfy the provided predicate .
&self
predicate
&Predicate
&self
predicate
&Predicate