susumu.yata
null+****@clear*****
Thu Jul 24 17:59:20 JST 2014
susumu.yata 2014-07-24 17:59:20 +0900 (Thu, 24 Jul 2014) New Revision: 2a25af74f61f52783b657d7e8531de9e92f00e23 https://github.com/groonga/grnxx/commit/2a25af74f61f52783b657d7e8531de9e92f00e23 Message: Prepare for sorting. Modified files: include/grnxx/order.hpp include/grnxx/sorter.hpp include/grnxx/types.hpp lib/grnxx/sorter.cpp Modified: include/grnxx/order.hpp (+1 -1) =================================================================== --- include/grnxx/order.hpp 2014-07-24 11:17:30 +0900 (f5c7f1b) +++ include/grnxx/order.hpp 2014-07-24 17:59:20 +0900 (348adbb) @@ -31,7 +31,7 @@ class OrderSet { // Return the "i"-th sort condition. // // If "i" is invalid, the result is undefined. - const Order &get(Int i) const { + Order &get(Int i) { return orders_[i]; } Modified: include/grnxx/sorter.hpp (+1 -0) =================================================================== --- include/grnxx/sorter.hpp 2014-07-24 11:17:30 +0900 (580fd48) +++ include/grnxx/sorter.hpp 2014-07-24 17:59:20 +0900 (3e4b886) @@ -56,6 +56,7 @@ class Sorter { private: RecordSet *record_set_; + unique_ptr<SorterNode> head_; Sorter(); }; Modified: include/grnxx/types.hpp (+1 -0) =================================================================== --- include/grnxx/types.hpp 2014-07-24 11:17:30 +0900 (aada258) +++ include/grnxx/types.hpp 2014-07-24 17:59:20 +0900 (0ffab64) @@ -409,6 +409,7 @@ class ExpressionNode; class ExpressionBuilder; class OrderSet; class OrderSetBuilder; +class SorterNode; class Sorter; } // namespace grnxx Modified: lib/grnxx/sorter.cpp (+147 -5) =================================================================== --- lib/grnxx/sorter.cpp 2014-07-24 11:17:30 +0900 (92a88b9) +++ lib/grnxx/sorter.cpp 2014-07-24 17:59:20 +0900 (8e3f48f) @@ -1,14 +1,145 @@ #include "grnxx/sorter.hpp" #include "grnxx/error.hpp" +#include "grnxx/expression.hpp" +#include "grnxx/order.hpp" +#include "grnxx/record.hpp" namespace grnxx { + +class SorterNode { + public: + static unique_ptr<SorterNode> create(Error *error, Order &&order); + + SorterNode() : next_(nullptr) {} + virtual ~SorterNode() {} + + // Return the next node. + SorterNode *next() const { + return next_.get(); + } + // Set the next node. + void set_next(unique_ptr<SorterNode> &&next) { + next_ = std::move(next); + } + + // Sort records in [begin, end). + // + // On success, returns true. + // On failure, returns false and stores error information into "*error" if + // "error" != nullptr. + virtual bool sort(Error *error, + RecordSet *record_set, + Int begin, + Int end) = 0; + + private: + unique_ptr<SorterNode> next_; +}; + namespace { -// TODO +template <typename T> +struct RegularComparer { + using Value = T; + bool operator()(T lhs, T rhs) const { + return lhs < rhs; + } +}; + +template <typename T> +struct ReverseComparer { + using Value = T; + bool operator()(T lhs, T rhs) const { + return rhs < lhs; + } +}; + +template <typename T> +class Node : public SorterNode { + public: + using Value = typename T::Value; + + Node(Order &&order) : SorterNode(), order_(std::move(order)) {} + ~Node() {} + + bool sort(Error *error, RecordSet *record_set, Int begin, Int end); + + private: + Order order_; + std::vector<Value> values_; + + // TODO: A pointer to records is not available. +// void quick_sort(Record *records, Value *values, Int size, +// Int begin, Int end); +// void insertion_sort(Record *records, Value *values, Int size); +// void move_pivot_first(Record *records, Value *values, Int size); +}; + +template <typename T> +bool Node<T>::sort(Error *error, RecordSet *record_set, Int begin, Int end) { + return false; +} } // namespace +unique_ptr<SorterNode> SorterNode::create(Error *error, Order &&order) { + unique_ptr<SorterNode> node; + switch (order.expression->data_type()) { + // TODO: Bool type does not support pointer. +// case BOOL_DATA: { +// node.reset(new (nothrow) Node<Bool>(std::move(order))); +// break; +// } + case INT_DATA: { + if (order.type == REGULAR_ORDER) { + node.reset(new (nothrow) Node<RegularComparer<Int>>(std::move(order))); + } else { + node.reset(new (nothrow) Node<ReverseComparer<Int>>(std::move(order))); + } + break; + } + case FLOAT_DATA: { + if (order.type == REGULAR_ORDER) { + node.reset( + new (nothrow) Node<RegularComparer<Float>>(std::move(order))); + } else { + node.reset( + new (nothrow) Node<ReverseComparer<Float>>(std::move(order))); + } + break; + } + case TIME_DATA: { + if (order.type == REGULAR_ORDER) { + node.reset( + new (nothrow) Node<RegularComparer<Time>>(std::move(order))); + } else { + node.reset( + new (nothrow) Node<ReverseComparer<Time>>(std::move(order))); + } + break; + } + case TEXT_DATA: { + if (order.type == REGULAR_ORDER) { + node.reset( + new (nothrow) Node<RegularComparer<Text>>(std::move(order))); + } else { + node.reset( + new (nothrow) Node<ReverseComparer<Text>>(std::move(order))); + } + break; + } + default: { + GRNXX_ERROR_SET(error, NOT_SUPPORTED_YET, "Not supported yet"); + return nullptr; + } + } + if (!node) { + GRNXX_ERROR_SET(error, NO_MEMORY, "Memory allocation failed"); + } + return node; +} + Sorter::~Sorter() {} unique_ptr<Sorter> Sorter::create( @@ -20,6 +151,16 @@ unique_ptr<Sorter> Sorter::create( GRNXX_ERROR_SET(error, NO_MEMORY, "Memory allocation failed"); return nullptr; } + for (Int i = order_set->size() - 1; i >= 0; --i) { + unique_ptr<SorterNode> node( + SorterNode::create(error, std::move(order_set->get(i)))); + if (!node) { + return nullptr; + } + node->set_next(std::move(sorter->head_)); + sorter->head_ = std::move(node); + } + order_set.reset(); return sorter; } @@ -38,15 +179,16 @@ bool Sorter::finish(Error *error) { // Nothing to do. return true; } - // TODO: Sorting is not supported yet. - GRNXX_ERROR_SET(error, NOT_SUPPORTED_YET, "Not supported yet"); - return false; + if (record_set_->size() <= 1) { + return true; + } + return head_->sort(error, record_set_, 0, record_set_->size()); } bool Sorter::sort(Error *error, RecordSet *record_set) { return reset(error, record_set) && finish(error); } -Sorter::Sorter() : record_set_(nullptr) {} +Sorter::Sorter() : record_set_(nullptr), head_() {} } // namespace grnxx -------------- next part -------------- HTML����������������������������...Download