Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat] Filter & Log Stream Operation #88

Closed
wants to merge 16 commits into from
Closed

Conversation

IHEII
Copy link
Contributor

@IHEII IHEII commented Jan 5, 2024

Summary

  • Implement a simple filter
  • Implement new RPC protocol -- ObTableLSOperation (ObTableLSOperation may be refactored to be more effective and robust in the future)

Solution Description

* #L%
*/

#![allow(dead_code)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it necessary to disable dead_code and unused_macros check?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

pub struct ObTableValueFilter {
pub op: ObCompareOperator,
pub column_name: String,
pub value: String,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The filter only supports String column filtering (in rust it must be encoded as valid utf-8)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use string to pass the message to the server. The OB Server will parse this string to extract the filter ( Filter may be refactored in the future). Although I considered using T to store the value of this filter, the complexity of the existing code necessitates the continued use of a string for this purpose. ( Since we only support ObTableValueFilter on numeric type and string type, using string to store the value of filter is considerable)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we only support ObTableValueFilter on numeric type and string type

If so, I guess some comments about this should be added to this struct.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

src/client/filter.rs Outdated Show resolved Hide resolved
src/client/filter.rs Outdated Show resolved Hide resolved
pub struct ObTableValueFilter {
pub op: ObCompareOperator,
pub column_name: String,
pub value: String,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we only support ObTableValueFilter on numeric type and string type

If so, I guess some comments about this should be added to this struct.

}

impl ObTableValueFilter {
pub fn new<U: ToString, V: ToString>(op: ObCompareOperator, column_name: U, value: V) -> Self {
Copy link
Contributor

@ShiKaiWi ShiKaiWi Jan 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess column_name must be String type, so the U is unnecssary here?
And I guess IntoString may be a better type for value (no clone when the real type is string).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed


const TABLE_COMPARE_FILTER_PREFIX: &str = "TableCompareFilter";

pub trait Filter: Any {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the rust, there are two ways to achieve the polymorphism:

  • trait object
  • enum

And here I find the as_any is used for downcasting, and it's not a good pattern when using trait object. And if the details of the underlying implementation are necessary, enum may be a good choice:

pub enum Filter {
     Value(ObTableValueFilter),
     List(ObTableFilterList),
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Comment on lines 24 to 25
fn string(&self) -> String;
fn concat_string(&self, filter_string: &mut String);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about such names:

Suggested change
fn string(&self) -> String;
fn concat_string(&self, filter_string: &mut String);
/// Encode the filter as string.
fn encode(&self) -> String;
/// Encode the filter to the buffer.
fn encode_to&self, buffer: &mut String);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

self.flags
}

pub fn set_is_check_and_execute(&mut self, is_check_and_execute: bool) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly, is_xxx is used for method name, so how about rename it as:

Suggested change
pub fn set_is_check_and_execute(&mut self, is_check_and_execute: bool) {
pub fn set_is_check_and_execute(&mut self, check_and_execute: bool) {

}
}

pub fn set_is_check_not_exists(&mut self, is_check_not_exists: bool) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub fn set_is_check_not_exists(&mut self, is_check_not_exists: bool) {
pub fn set_check_not_exists(&mut self, check_not_exists: bool) {

}

impl ObTableQueryAndMutate {
pub fn internal_new(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If its name is internal_new, shall we make it as private method?

Comment on lines 728 to 735
pub fn check_and_insert_up<T: FilterEncoder>(
&mut self,
row_keys: Vec<Value>,
columns: Vec<String>,
properties: Vec<Value>,
filter: T,
check_exist: bool,
) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about this name:

Suggested change
pub fn check_and_insert_up<T: FilterEncoder>(
&mut self,
row_keys: Vec<Value>,
columns: Vec<String>,
properties: Vec<Value>,
filter: T,
check_exist: bool,
) {
pub fn check_and_upsert(
&mut self,
row_keys: Vec<Value>,
columns: Vec<String>,
properties: Vec<Value>,
filter: impl FilterEncoder,
check_exist: bool,
) {

Comment on lines +724 to +727
/// check the data with corresponding row_keys
/// whether meet the filter and execute the insertUp
/// if check_exist is true: check if any data meet the filter
/// if check_exist is false: check if all data do not meet the filter
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't understand the check_exist parameter. The comment about it seems confusing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After some discussions, I guess we can hide the check_exist parameter, and provide two methods:

check_and_upsert_if_exists
check_and_upsert_if_not_exists

And it may lead to less confusion.

Comment on lines +161 to +163
#[derive(Debug, Clone)]
/// Only support [`ObTableValueFilter`] on numeric type and string type
/// The value will be encoded into string and will be parsed into filter in the server
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#[derive(Debug, Clone)]
/// Only support [`ObTableValueFilter`] on numeric type and string type
/// The value will be encoded into string and will be parsed into filter in the server
/// Only support [`ObTableValueFilter`] on numeric type and string type
/// The value will be encoded into string and will be parsed into filter in the server
#[derive(Debug, Clone)]

Comment on lines +724 to +727
/// check the data with corresponding row_keys
/// whether meet the filter and execute the insertUp
/// if check_exist is true: check if any data meet the filter
/// if check_exist is false: check if all data do not meet the filter
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After some discussions, I guess we can hide the check_exist parameter, and provide two methods:

check_and_upsert_if_exists
check_and_upsert_if_not_exists

And it may lead to less confusion.

Comment on lines +460 to +463
// whether a check_and_execute option
pub check_and_execute: bool,
// check whether any data meet the filter in check_and_execute
pub check_exist: bool,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// whether a check_and_execute option
pub check_and_execute: bool,
// check whether any data meet the filter in check_and_execute
pub check_exist: bool,
/// Whether a check_and_execute option
pub check_and_execute: bool,
/// check whether any data meet the filter in check_and_execute
pub check_exists: bool,

BTW, the comment

check whether any data meet the filter in check_and_execute

The check_and_execute seems just a boolean, where is the filter in it?

@IHEII IHEII closed this Mar 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants