From fd164fe3d1aad679e66f13308a2ea085447a57b8 Mon Sep 17 00:00:00 2001 From: gal salomon Date: Mon, 14 Mar 2022 10:42:36 +0200 Subject: [PATCH] using reference to object::value in order to reduce the creation of temporary objects Signed-off-by: gal salomon --- include/s3select_functions.h | 102 +++++++++++++++-------------------- include/s3select_oper.h | 78 +++++++++++++++++++-------- 2 files changed, 99 insertions(+), 81 deletions(-) diff --git a/include/s3select_functions.h b/include/s3select_functions.h index c9a981dd..4582c65b 100644 --- a/include/s3select_functions.h +++ b/include/s3select_functions.h @@ -503,7 +503,6 @@ class __function : public base_statement struct _fn_add : public base_function { - value var_result; bool operator()(bs_stmt_vec_t* args, variable* result) override { @@ -512,7 +511,7 @@ struct _fn_add : public base_function iter++; base_statement* y = *iter; - var_result = x->eval() + y->eval(); + value& var_result = x->eval() + y->eval(); *result = var_result; @@ -596,7 +595,7 @@ struct _fn_avg : public base_function try { sum = sum + x->eval(); - count++; + count = count + 1; } catch (base_s3select_exception &e) { @@ -631,9 +630,10 @@ struct _fn_min : public base_function auto iter = args->begin(); base_statement* x = *iter; - if(min > x->eval()) + value& tmp = x->eval(); + if(min > tmp) { - min=x->eval(); + min=tmp; } return true; @@ -661,9 +661,10 @@ struct _fn_max : public base_function auto iter = args->begin(); base_statement* x = *iter; - if(max < x->eval()) + value& tmp = x->eval(); + if(max < tmp) { - max=x->eval(); + max=tmp; } return true; @@ -682,7 +683,7 @@ struct _fn_to_int : public base_function bool operator()(bs_stmt_vec_t* args, variable* result) override { - value v = (*args->begin())->eval(); + value& v = (*args->begin())->eval(); switch (v.type) { @@ -727,7 +728,7 @@ struct _fn_to_float : public base_function bool operator()(bs_stmt_vec_t* args, variable* result) override { - value v = (*args->begin())->eval(); + value& v = (*args->begin())->eval(); switch (v.type) { @@ -833,7 +834,6 @@ struct _fn_to_timestamp : public base_function bsc::rule<> d_date_time = ((d_yyyymmdd_dig) >> (d_time_dig)) | (d_yyyymmdd_dig) | (d_yyyy_dig); timestamp_t tmstmp; - value v_str; int tz_hour, tz_min; bool datetime_validation() @@ -920,7 +920,7 @@ struct _fn_to_timestamp : public base_function base_statement* str = *iter; - v_str = str->eval(); + value& v_str = str->eval(); if (v_str.type != value::value_En_t::STRING) { @@ -1420,9 +1420,9 @@ struct _fn_between : public base_function iter++; base_statement* main_expr = *iter; - value second_expr_val = second_expr->eval(); - value first_expr_val = first_expr->eval(); - value main_expr_val = main_expr->eval(); + value& second_expr_val = second_expr->eval(); + value& first_expr_val = first_expr->eval(); + value& main_expr_val = main_expr->eval(); if ((second_expr_val.type == first_expr_val.type && first_expr_val.type == main_expr_val.type) || (second_expr_val.is_number() && first_expr_val.is_number() && main_expr_val.is_number())) { @@ -1458,7 +1458,7 @@ struct _fn_isnull : public base_function { auto iter = args->begin(); base_statement* expr = *iter; - value expr_val = expr->eval(); + value& expr_val = expr->eval(); if ( expr_val.is_null()) { result->set_value(true); } else { @@ -1496,12 +1496,12 @@ struct _fn_in : public base_function { int args_size = static_cast(args->size()-1); base_statement *main_expr = (*args)[args_size]; - value main_expr_val = main_expr->eval(); + value& main_expr_val = main_expr->eval(); args_size--; while (args_size>=0) { base_statement *expr = (*args)[args_size]; - value expr_val = expr->eval(); + value& expr_val = expr->eval(); args_size--; if ((expr_val.type == main_expr_val.type) || (expr_val.is_number() && main_expr_val.is_number())) { @@ -1519,7 +1519,6 @@ struct _fn_in : public base_function struct _fn_like : public base_function { - value res; std::regex compiled_regex; bool constant_state; value like_expr_val; @@ -1544,8 +1543,8 @@ struct _fn_like : public base_function if(constant_state == true) { - escape_expr_val = esc->eval(); - like_expr_val = like_expr->eval(); + escape_expr_val.set_value(esc->eval()); + like_expr_val.set_value(like_expr->eval()); if (like_expr_val.type != value::value_En_t::STRING) { throw base_s3select_exception("like expression must be string"); @@ -1765,8 +1764,8 @@ bool operator()(bs_stmt_vec_t* args, variable* result) override base_statement* main_expr = *iter; if (constant_state == false){ - like_expr_val = like_expr->eval(); - escape_expr_val = escape_expr->eval(); + like_expr_val.set_value(like_expr->eval()); + escape_expr_val.set_value(escape_expr->eval()); if (like_expr_val.type != value::value_En_t::STRING) { throw base_s3select_exception("like expression must be string"); @@ -1781,7 +1780,7 @@ bool operator()(bs_stmt_vec_t* args, variable* result) override compiled_regex = std::regex(like_as_regex_str); } - value main_expr_val = main_expr->eval(); + value& main_expr_val = main_expr->eval(); if (main_expr_val.type != value::value_En_t::STRING) { throw base_s3select_exception("main expression must be string"); } @@ -1802,8 +1801,6 @@ struct _fn_substr : public base_function //it prevent from intensive use of malloc/free (fragmentation). //should validate result length. //TODO may replace by std::string (dynamic) , or to replace with global allocator , in query scope. - value v_str; - value v_from; value v_to; bool operator()(bs_stmt_vec_t* args, variable* result) override @@ -1826,14 +1823,14 @@ struct _fn_substr : public base_function { iter++; to = *iter; - v_to = to->eval(); + v_to.set_value(to->eval()); if (!v_to.is_number()) { throw base_s3select_exception("substr third argument must be number"); //can skip row } } - v_str = str->eval(); + value& v_str = str->eval(); if(v_str.type != value::value_En_t::STRING) { @@ -1842,7 +1839,7 @@ struct _fn_substr : public base_function int str_length = strlen(v_str.str()); - v_from = from->eval(); + value& v_from = from->eval(); if(!v_from.is_number()) { throw base_s3select_exception("substr second argument must be number"); //can skip current row @@ -1923,13 +1920,12 @@ struct _fn_substr : public base_function struct _fn_charlength : public base_function { - value v_str; bool operator()(bs_stmt_vec_t* args, variable* result) override { auto iter = args->begin(); base_statement* str = *iter; - v_str = str->eval(); + value& v_str = str->eval(); if(v_str.type != value::value_En_t::STRING) { throw base_s3select_exception("content is not string!"); } else { @@ -1943,13 +1939,12 @@ struct _fn_charlength : public base_function { struct _fn_lower : public base_function { std::string buff; - value v_str; bool operator()(bs_stmt_vec_t* args, variable* result) override { auto iter = args->begin(); base_statement* str = *iter; - v_str = str->eval(); + value& v_str = str->eval(); if(v_str.type != value::value_En_t::STRING) { throw base_s3select_exception("content is not string"); } else { @@ -1964,13 +1959,12 @@ struct _fn_lower : public base_function { struct _fn_upper : public base_function { std::string buff; - value v_str; bool operator()(bs_stmt_vec_t* args, variable* result) override { auto iter = args->begin(); base_statement* str = *iter; - v_str = str->eval(); + value& v_str = str->eval(); if(v_str.type != value::value_En_t::STRING) { throw base_s3select_exception("content is not string"); } else { @@ -1984,8 +1978,6 @@ struct _fn_upper : public base_function { struct _fn_nullif : public base_function { - value x; - value y; bool operator()(bs_stmt_vec_t* args, variable* result) override { @@ -1997,10 +1989,10 @@ struct _fn_nullif : public base_function { throw base_s3select_exception("nullif accept only 2 arguments"); } base_statement *first = *iter; - x = first->eval(); + value& x = first->eval(); iter++; base_statement *second = *iter; - y = second->eval(); + value& y = second->eval(); if (x.is_null() && y.is_null()) { result->set_null(); @@ -2028,7 +2020,6 @@ struct _fn_nullif : public base_function { struct _fn_when_then : public base_function { - value when_value; bool operator()(bs_stmt_vec_t* args, variable* result) override { @@ -2039,7 +2030,7 @@ struct _fn_when_then : public base_function { base_statement* when_expr = *iter; - when_value = when_expr->eval(); + value& when_value = when_expr->eval(); if (when_value.is_true())//true { @@ -2055,9 +2046,6 @@ struct _fn_when_then : public base_function { struct _fn_when_value_then : public base_function { - value when_value; - value case_value; - value then_value; bool operator()(bs_stmt_vec_t* args, variable* result) override { @@ -2071,9 +2059,9 @@ struct _fn_when_value_then : public base_function { base_statement* case_expr = *iter; - when_value = when_expr->eval(); - case_value = case_expr->eval(); - then_value = then_expr->eval(); + value& when_value = when_expr->eval(); + value& case_value = case_expr->eval(); + value& then_value = then_expr->eval(); if (case_value == when_value) { @@ -2088,7 +2076,6 @@ struct _fn_when_value_then : public base_function { struct _fn_case_when_else : public base_function { - value when_then_value; bool operator()(bs_stmt_vec_t* args, variable* result) override { @@ -2098,7 +2085,7 @@ struct _fn_case_when_else : public base_function { for(int ivec=args_size;ivec>0;ivec--) { - when_then_value = (*args)[ivec]->eval(); + value& when_then_value = (*args)[ivec]->eval(); if(!when_then_value.is_null()) { @@ -2125,7 +2112,7 @@ struct _fn_coalesce : public base_function while (args_size >= 1) { base_statement* expr = *iter_begin; - value expr_val = expr->eval(); + value& expr_val = expr->eval(); iter_begin++; if ( !(expr_val.is_null())) { *result = expr_val; @@ -2148,7 +2135,7 @@ struct _fn_string : public base_function auto iter = args->begin(); base_statement* expr = *iter; - value expr_val = expr->eval(); + value& expr_val = expr->eval(); result->set_value((expr_val.to_string())); return true; } @@ -2157,12 +2144,11 @@ struct _fn_string : public base_function struct _fn_to_bool : public base_function { - value func_arg; bool operator()(bs_stmt_vec_t* args, variable* result) override { int64_t i=0; - func_arg = (*args->begin())->eval(); + value& func_arg = (*args->begin())->eval(); if (func_arg.type == value::value_En_t::FLOAT) { @@ -2204,7 +2190,7 @@ struct _fn_trim : public base_function { auto iter = args->begin(); int args_size = args->size(); base_statement* str = *iter; - v_input = str->eval(); + v_input.set_value(str->eval()); if(v_input.type != value::value_En_t::STRING) { throw base_s3select_exception("content is not string"); } @@ -2212,7 +2198,7 @@ struct _fn_trim : public base_function { if (args_size == 2) { iter++; base_statement* next = *iter; - v_remove = next->eval(); + v_remove.set_value(next->eval()); } boost::trim_right_if(input_string,boost::is_any_of(v_remove.str())); boost::trim_left_if(input_string,boost::is_any_of(v_remove.str())); @@ -2237,7 +2223,7 @@ struct _fn_leading : public base_function { auto iter = args->begin(); int args_size = args->size(); base_statement* str = *iter; - v_input = str->eval(); + v_input.set_value(str->eval()); if(v_input.type != value::value_En_t::STRING) { throw base_s3select_exception("content is not string"); } @@ -2245,7 +2231,7 @@ struct _fn_leading : public base_function { if (args_size == 2) { iter++; base_statement* next = *iter; - v_remove = next->eval(); + v_remove.set_value(next->eval()); } boost::trim_left_if(input_string,boost::is_any_of(v_remove.str())); result->set_value(input_string.c_str()); @@ -2269,7 +2255,7 @@ struct _fn_trailing : public base_function { auto iter = args->begin(); int args_size = args->size(); base_statement* str = *iter; - v_input = str->eval(); + v_input.set_value(str->eval()); if(v_input.type != value::value_En_t::STRING) { throw base_s3select_exception("content is not string"); } @@ -2277,7 +2263,7 @@ struct _fn_trailing : public base_function { if (args_size == 2) { iter++; base_statement* next = *iter; - v_remove = next->eval(); + v_remove.set_value(next->eval()); } boost::trim_right_if(input_string,boost::is_any_of(v_remove.str())); result->set_value(input_string.c_str()); diff --git a/include/s3select_oper.h b/include/s3select_oper.h index 0c5181cb..fec7f9e8 100644 --- a/include/s3select_oper.h +++ b/include/s3select_oper.h @@ -463,6 +463,36 @@ class value __val.str = m_str_value.data(); } + void set_value(value& val_o) + { + if(val_o.type == value_En_t::STRING) + { + m_str_value.assign(val_o.str()); + __val.str = m_str_value.data(); + } + else + { + this->__val = val_o.__val; + } + + this->type = val_o.type; + } + + value(const value& v) + { + if(v.type == value_En_t::STRING) + { + this->m_str_value.assign(v.__val.str);//(v.str()); + this->__val.str = this->m_str_value.data(); + } + else + { + this->__val = v.__val; + } + + this->type = v.type; + } + ~value() {//TODO should be a part of the cleanup routine(__function::push_for_cleanup) multiple_values.values.clear(); @@ -929,12 +959,20 @@ class value return compute(*this, v); } + value& operator+(int i) + { + *this = *this + static_cast(i); + return *this; + } + +#if 0 value operator++(int) { *this = *this + static_cast(1); return *this; } - +#endif + value& operator-(const value& v) { return compute(*this, v); @@ -1003,7 +1041,7 @@ class scratch_area scratch_area():m_upper_bound(-1),parquet_type(false),buff_loc(0) { - m_schema_values = new std::vector(128,value("")); + m_schema_values = new std::vector(128); } ~scratch_area() @@ -1364,9 +1402,8 @@ class variable : public base_statement std::string _name; int column_pos; value var_value; - std::string m_star_op_result; char m_star_op_result_charc[4096]; //TODO cause larger allocations for other objects containing variable (dynamic is one solution) - value star_operation_values[16];//TODO cause larger allocations for other objects containing variable (dynamic is one solution) + std::vector star_operation_values; const int undefined_column_pos = -1; const int column_alias = -2; @@ -1516,11 +1553,6 @@ class variable : public base_statement size_t num_of_columns = m_scratch->get_num_of_columns(); var_value.multiple_values.clear(); //TODO var_value.clear()?? - if(sizeof(star_operation_values)/sizeof(value) < num_of_columns) - { - throw base_s3select_exception(std::string("not enough memory for star-operation"), base_s3select_exception::s3select_exp_en_t::FATAL); - } - for(size_t i=0; iget_column_value(i).size(); @@ -1532,8 +1564,9 @@ class variable : public base_statement memcpy(&m_star_op_result_charc[pos], m_scratch->get_column_value(i).data(), len);//TODO using string_view will avoid copy m_star_op_result_charc[ pos + len ] = 0; - star_operation_values[i] = &m_star_op_result_charc[pos];//set string value - var_value.multiple_values.push_value( &star_operation_values[i] ); + value v1(m_star_op_result_charc+pos); + star_operation_values.push_back(v1); + var_value.multiple_values.push_value( &star_operation_values.back() ); pos += len; pos ++; @@ -1590,7 +1623,7 @@ class variable : public base_statement if (m_projection_alias->is_result_cached() == false) { - var_value = m_projection_alias->eval(); + var_value.set_value(m_projection_alias->eval()); m_projection_alias->set_result_cache(var_value); } else @@ -1775,14 +1808,14 @@ class logical_operand : public base_statement { throw base_s3select_exception("missing operand for logical ", base_s3select_exception::s3select_exp_en_t::FATAL); } - value a = l->eval(); + value& a = l->eval(); if (_oplog == oplog_t::AND) { if (!a.is_null() && a.i64() == false) { bool res = false ^ negation_result; return var_value = res; } - value b = r->eval(); + value& b = r->eval(); if(!b.is_null() && b.i64() == false) { bool res = false ^ negation_result; return var_value = res; @@ -1802,7 +1835,7 @@ class logical_operand : public base_statement bool res = true ^ negation_result; return var_value = res; } - value b = r->eval(); + value& b = r->eval(); if(b.is_true() == true) { bool res = true ^ negation_result; return var_value = res; @@ -2037,7 +2070,6 @@ class base_function class base_date_extract : public base_function { protected: - value val_timestamp; boost::posix_time::ptime new_ptime; boost::posix_time::time_duration td; bool flag; @@ -2054,7 +2086,7 @@ class base_date_extract : public base_function } base_statement* ts = *iter; - val_timestamp = ts->eval(); + value& val_timestamp = ts->eval(); if(val_timestamp.is_timestamp()== false) { throw base_s3select_exception("second parameter is not timestamp"); @@ -2083,7 +2115,7 @@ class base_date_diff : public base_function } base_statement* dt1_param = *iter; - value val_ts1 = dt1_param->eval(); + value& val_ts1 = dt1_param->eval(); if (val_ts1.is_timestamp() == false) { @@ -2092,7 +2124,7 @@ class base_date_diff : public base_function iter++; base_statement* dt2_param = *iter; - value val_ts2 = dt2_param->eval(); + value& val_ts2 = dt2_param->eval(); if (val_ts2.is_timestamp() == false) { @@ -2136,7 +2168,7 @@ class base_date_add : public base_function } base_statement* quan = *iter; - val_quantity = quan->eval(); + val_quantity.set_value(quan->eval()); if (val_quantity.is_number() == false) { @@ -2145,7 +2177,7 @@ class base_date_add : public base_function iter++; base_statement* ts = *iter; - value val_ts = ts->eval(); + value& val_ts = ts->eval(); if(val_ts.is_timestamp() == false) { @@ -2588,7 +2620,7 @@ class base_timestamp_to_string : public base_function } base_statement* dt1_param = *iter; - value val_timestamp = dt1_param->eval(); + value& val_timestamp = dt1_param->eval(); if (val_timestamp.is_timestamp() == false) { @@ -2597,7 +2629,7 @@ class base_timestamp_to_string : public base_function iter++; base_statement* frmt = *iter; - value val_format = frmt->eval(); + value& val_format = frmt->eval(); if (val_format.is_string() == false) {