susumu.yata
null+****@clear*****
Wed Mar 5 14:59:15 JST 2014
susumu.yata 2014-03-05 14:59:15 +0900 (Wed, 05 Mar 2014) New Revision: 9b70515447d41424051099ee6ebacf21dddfca19 https://github.com/groonga/grnxx/commit/9b70515447d41424051099ee6ebacf21dddfca19 Message: Change LOGICAL_AND not to evaluate rhs if lhs == FALSE. Redmine: refs #2354. Modified files: lib/grnxx/calc_impl.cpp Modified: lib/grnxx/calc_impl.cpp (+29 -5) =================================================================== --- lib/grnxx/calc_impl.cpp 2014-03-05 14:55:24 +0900 (ce8508f) +++ lib/grnxx/calc_impl.cpp 2014-03-05 14:59:15 +0900 (55f5095) @@ -274,7 +274,8 @@ class LogicalAndNode : public OperatorNode<Boolean> { explicit LogicalAndNode(CalcNode *lhs, CalcNode *rhs) : OperatorNode<Boolean>(), lhs_(static_cast<T *>(lhs)), - rhs_(static_cast<U *>(rhs)) {} + rhs_(static_cast<U *>(rhs)), + local_row_ids_() {} // ノードを破棄する. ~LogicalAndNode() {} @@ -287,6 +288,7 @@ class LogicalAndNode : public OperatorNode<Boolean> { private: T *lhs_; U *rhs_; + std::vector<RowID> local_row_ids_; }; // 行の一覧を受け取り,演算結果が真になる行のみを残して,残った行の数を返す. @@ -300,12 +302,34 @@ Int64 LogicalAndNode<T, U>::filter(RowID *row_ids, Int64 num_row_ids) { // 与えられた行の一覧について演算をおこない,その結果を取得できる状態にする. template <typename T, typename U> void LogicalAndNode<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) { - data_[i] = lhs_->get(i, row_ids[i]) && rhs_->get(i, 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) { + auto lhs_value = lhs_->get(i, row_ids[i]); + if (lhs_value) { + data_[i] = rhs_->get(j, row_ids[j]); + ++j; + } else { + data_[i] = lhs_value; + } } } -------------- next part -------------- HTML����������������������������...Download