susumu.yata
null+****@clear*****
Wed Mar 5 15:05:43 JST 2014
susumu.yata 2014-03-05 15:05:43 +0900 (Wed, 05 Mar 2014) New Revision: 047ac02bb45109d5aca78a9d78fb91bf583c61f2 https://github.com/groonga/grnxx/commit/047ac02bb45109d5aca78a9d78fb91bf583c61f2 Message: Change LOGICAL_OR not to evaluate rhs if lhs == TRUE. Redmine: refs #2354. Modified files: lib/grnxx/calc_impl.cpp Modified: lib/grnxx/calc_impl.cpp (+26 -4) =================================================================== --- lib/grnxx/calc_impl.cpp 2014-03-05 14:59:15 +0900 (55f5095) +++ lib/grnxx/calc_impl.cpp 2014-03-05 15:05:43 +0900 (826f82a) @@ -429,12 +429,34 @@ Int64 LogicalOrNode<T, U>::filter(RowID *row_ids, Int64 num_row_ids) { // 与えられた行の一覧について演算をおこない,その結果を取得できる状態にする. template <typename T, typename U> void LogicalOrNode<T, U>::fill(const RowID *row_ids, Int64 num_row_ids) { - // TODO: 左側が真になるときは右側を評価しないようにする. - lhs_->fill(row_ids, num_row_ids); - rhs_->fill(row_ids, num_row_ids); + // 必要な領域を確保する. data_.resize(num_row_ids); + local_row_ids_.resize(num_row_ids); + + lhs_->fill(row_ids, num_row_ids); + + // 左側の評価が偽になる行のみを抜き出す. + Int64 count = 0; + for (Int64 i = 0; i < num_row_ids; ++i) { + RowID row_id = row_ids[i]; + if (!lhs_->get(i, row_id)) { + local_row_ids_[count] = row_id; + ++count; + } + } + + rhs_->fill(&*local_row_ids_.begin(), count); + + // 左右ともに真になる行のみ真にする. + Int64 j = 0; for (Int64 i = 0; i < num_row_ids; ++i) { - data_[i] = lhs_->get(i, row_ids[i]) || rhs_->get(i, row_ids[i]); + auto lhs_value = lhs_->get(i, row_ids[i]); + if (lhs_value) { + data_[i] = lhs_value; + } else { + data_[i] = rhs_->get(j, row_ids[j]); + ++j; + } } } -------------- next part -------------- HTML����������������������������...Download