susumu.yata
null+****@clear*****
Tue Mar 4 12:24:13 JST 2014
susumu.yata 2014-03-04 12:24:13 +0900 (Tue, 04 Mar 2014) New Revision: 23d27918dc303f84310193ed590faca131f061b2 https://github.com/groonga/grnxx/commit/23d27918dc303f84310193ed590faca131f061b2 Message: Implement variable-size integer column. It is enabled if --enable-varint is specified to ./configure. Modified files: configure.ac lib/grnxx/column_impl.cpp lib/grnxx/column_impl.hpp Modified: configure.ac (+11 -0) =================================================================== --- configure.ac 2014-03-04 10:34:46 +0900 (c611975) +++ configure.ac 2014-03-04 12:24:13 +0900 (354229a) @@ -34,6 +34,17 @@ AC_SUBST([AM_LTLDFLAGS]) # Checks for libraries. +AC_ARG_ENABLE([varint], + [AS_HELP_STRING([--enable-varint], + [enable variable integer type [default=no]])], + [], + [enable_varint="no"]) +if test "x$enable_varint" != "xno"; then + AC_DEFINE(GRNXX_ENABLE_VARIABLE_INTEGER_TYPE, + [1], + [Define to 1 for variable integer type]) +fi + AC_ARG_ENABLE([backtrace], [AS_HELP_STRING([--enable-backtrace], [show backtrace on error [default=no]])], Modified: lib/grnxx/column_impl.cpp (+199 -1) =================================================================== --- lib/grnxx/column_impl.cpp 2014-03-04 10:34:46 +0900 (8e96392) +++ lib/grnxx/column_impl.cpp 2014-03-04 12:24:13 +0900 (016d030) @@ -2,6 +2,8 @@ #include "grnxx/index.hpp" +#include <iostream> + namespace grnxx { // カラムを初期化する. @@ -53,9 +55,205 @@ void ColumnImpl<T>::set(RowID row_id, T value) { } template class ColumnImpl<Boolean>; -template class ColumnImpl<Int64>; template class ColumnImpl<Float>; +#ifdef GRNXX_ENABLE_VARIABLE_INTEGER_TYPE + +// カラムを初期化する. +ColumnImpl<Int64>::ColumnImpl(Table *table, ColumnID id, const String &name) + : Column(table, id, name, INTEGER), + data_8_(MIN_ROW_ID, 0), + data_16_(), + data_32_(), + data_64_(), + internal_data_type_size_(8), + indexes_() {} + +// カラムを破棄する. +ColumnImpl<Int64>::~ColumnImpl() {} + +// 指定された索引との関連付けをおこなう. +bool ColumnImpl<Int64>::register_index(Index *index) { + auto it = std::find(indexes_.begin(), indexes_.end(), index); + if (it != indexes_.end()) { + return false; + } + indexes_.push_back(index); + return true; +} + +// 指定された索引との関連を削除する. +bool ColumnImpl<Int64>::unregister_index(Index *index) { + auto it = std::find(indexes_.begin(), indexes_.end(), index); + if (it == indexes_.end()) { + return false; + } + indexes_.erase(it); + return true; +} + +// 指定された行 ID が使えるようにサイズを変更する. +void ColumnImpl<Int64>::resize(RowID max_row_id) { + switch (internal_data_type_size_) { + case 8: { + return data_8_.resize(max_row_id + 1, 0); + } + case 16: { + return data_16_.resize(max_row_id + 1, 0); + } + case 32: { + return data_32_.resize(max_row_id + 1, 0); + } + default: { + return data_64_.resize(max_row_id + 1, 0); + } + } +} + +// 指定された ID の値を更新する. +void ColumnImpl<Int64>::set(RowID row_id, Int64 value) { + switch (internal_data_type_size_) { + case 8: { + if ((value < INT8_MIN) || (value > INT8_MAX)) { + expand_and_set(row_id, value); + } else { + data_8_[row_id] = value; + } + break; + } + case 16: { + if ((value < INT16_MIN) || (value > INT16_MAX)) { + expand_and_set(row_id, value); + } else { + data_16_[row_id] = value; + } + break; + } + case 32: { + if ((value < INT32_MIN) || (value > INT32_MAX)) { + expand_and_set(row_id, value); + } else { + data_32_[row_id] = value; + } + break; + } + default: { + data_64_[row_id] = value; + break; + } + } + for (auto index : indexes_) { + index->insert(row_id); + } +} + +// 渡された値を格納できるように拡張をおこなってから値を格納する. +void ColumnImpl<Int64>::expand_and_set(RowID row_id, Int64 value) { + switch (internal_data_type_size_) { + case 8: { + if ((value < INT32_MIN) || (value > INT32_MAX)) { + // Int8 -> Int64. + std::cerr << "Log: " << name() << ": Int8 -> Int64" << std::endl; + data_64_.reserve(data_8_.capacity()); + data_64_.assign(data_8_.begin(), data_8_.end()); + data_64_[row_id] = value; + internal_data_type_size_ = 64; + } else if ((value < INT16_MIN) || (value > INT16_MAX)) { + // Int8 -> Int32. + std::cerr << "Log: " << name() << ": Int8 -> Int32" << std::endl; + data_32_.reserve(data_8_.capacity()); + data_32_.assign(data_8_.begin(), data_8_.end()); + data_32_[row_id] = value; + internal_data_type_size_ = 32; + } else { + // Int8 -> Int16. + std::cerr << "Log: " << name() << ": Int8 -> Int16" << std::endl; + data_16_.reserve(data_8_.capacity()); + data_16_.assign(data_8_.begin(), data_8_.end()); + data_16_[row_id] = value; + internal_data_type_size_ = 16; + } + std::vector<Int8>().swap(data_8_); + break; + } + case 16: { + if ((value < INT32_MIN) || (value > INT32_MAX)) { + // Int16 -> Int64. + std::cerr << "Log: " << name() << ": Int16 -> Int64" << std::endl; + data_64_.reserve(data_16_.capacity()); + data_64_.assign(data_16_.begin(), data_16_.end()); + data_64_[row_id] = value; + internal_data_type_size_ = 64; + } else if ((value < INT16_MIN) || (value > INT16_MAX)) { + // Int16 -> Int32. + std::cerr << "Log: " << name() << ": Int16 -> Int32" << std::endl; + data_32_.reserve(data_16_.capacity()); + data_32_.assign(data_16_.begin(), data_16_.end()); + data_32_[row_id] = value; + internal_data_type_size_ = 32; + } + std::vector<Int16>().swap(data_16_); + break; + } + case 32: { + // Int32 -> Int64. + std::cerr << "Log: " << name() << ": Int32-> Int64" << std::endl; + data_64_.reserve(data_32_.capacity()); + data_64_.assign(data_32_.begin(), data_32_.end()); + data_64_[row_id] = value; + internal_data_type_size_ = 64; + std::vector<Int32>().swap(data_32_); + break; + } + } +} + +#else // GRNXX_ENABLE_VARIABLE_INTEGER_TYPE + +// カラムを初期化する. +ColumnImpl<Int64>::ColumnImpl(Table *table, ColumnID id, const String &name) + : Column(table, id, name, INTEGER), + data_(MIN_ROW_ID, 0), + indexes_() {} + +// カラムを破棄する. +ColumnImpl<Int64>::~ColumnImpl() {} + +// 指定された索引との関連付けをおこなう. +bool ColumnImpl<Int64>::register_index(Index *index) { + auto it = std::find(indexes_.begin(), indexes_.end(), index); + if (it != indexes_.end()) { + return false; + } + indexes_.push_back(index); + return true; +} + +// 指定された索引との関連を削除する. +bool ColumnImpl<Int64>::unregister_index(Index *index) { + auto it = std::find(indexes_.begin(), indexes_.end(), index); + if (it == indexes_.end()) { + return false; + } + indexes_.erase(it); + return true; +} + +// 指定された行 ID が使えるようにサイズを変更する. +void ColumnImpl<Int64>::resize(RowID max_row_id) { + data_.resize(max_row_id + 1, 0); +} + +// 指定された ID の値を更新する. +void ColumnImpl<Int64>::set(RowID row_id, Int64 value) { + data_[row_id] = value; + for (auto index : indexes_) { + index->insert(row_id); + } +} + +#endif // GRNXX_ENABLE_VARIABLE_INTEGER_TYPE + // カラムを初期化する. ColumnImpl<String>::ColumnImpl(Table *table, ColumnID id, const String &name) : Column(table, id, name, TypeTraits<String>::data_type()), Modified: lib/grnxx/column_impl.hpp (+87 -0) =================================================================== --- lib/grnxx/column_impl.hpp 2014-03-04 10:34:46 +0900 (89ed32e) +++ lib/grnxx/column_impl.hpp 2014-03-04 12:24:13 +0900 (a0a3fc1) @@ -1,6 +1,7 @@ #ifndef GRNXX_COLUMN_IMPL_HPP #define GRNXX_COLUMN_IMPL_HPP +#include "../config.h" #include "grnxx/column.hpp" namespace grnxx { @@ -37,6 +38,92 @@ class ColumnImpl : public Column { std::vector<Index *> indexes_; }; +#ifdef GRNXX_ENABLE_VARIABLE_INTEGER_TYPE +template <> +class ColumnImpl<Int64> : public Column { + public: + // カラムを初期化する. + ColumnImpl(Table *table, ColumnID id, const String &name); + // カラムを破棄する. + ~ColumnImpl(); + + // コピーと代入を禁止する. + ColumnImpl(const ColumnImpl &) = delete; + ColumnImpl &operator=(const ColumnImpl &) = delete; + + // 指定された索引との関連付けをおこなう. + bool register_index(Index *index); + // 指定された索引との関連を削除する. + bool unregister_index(Index *index); + + // 指定された行 ID が使えるようにサイズを変更する. + void resize(RowID max_row_id); + + // 指定された ID の値を返す. + Int64 get(RowID row_id) const { + switch (internal_data_type_size_) { + case 8: { + return data_8_[row_id]; + } + case 16: { + return data_16_[row_id]; + } + case 32: { + return data_32_[row_id]; + } + default: { + return data_64_[row_id]; + } + } + } + // 指定された ID の値を更新する. + void set(RowID row_id, Int64 value); + + private: + std::vector<Int8> data_8_; + std::vector<Int16> data_16_; + std::vector<Int32> data_32_; + std::vector<Int64> data_64_; + Int64 internal_data_type_size_; + std::vector<Index *> indexes_; + + // 渡された値を格納できるように拡張をおこなってから値を格納する. + void expand_and_set(RowID row_id, Int64 value); +}; +#else // GRNXX_ENABLE_VARIABLE_INTEGER_TYPE +template <> +class ColumnImpl<Int64> : public Column { + public: + // カラムを初期化する. + ColumnImpl(Table *table, ColumnID id, const String &name); + // カラムを破棄する. + ~ColumnImpl(); + + // コピーと代入を禁止する. + ColumnImpl(const ColumnImpl &) = delete; + ColumnImpl &operator=(const ColumnImpl &) = delete; + + // 指定された索引との関連付けをおこなう. + bool register_index(Index *index); + // 指定された索引との関連を削除する. + bool unregister_index(Index *index); + + // 指定された行 ID が使えるようにサイズを変更する. + void resize(RowID max_row_id); + + // 指定された ID の値を返す. + Int64 get(RowID row_id) const { + return data_[row_id]; + } + // 指定された ID の値を更新する. + void set(RowID row_id, Int64 value); + + private: + std::vector<Int64> data_; + std::vector<Index *> indexes_; +}; +#endif // GRNXX_ENABLE_VARIABLE_INTEGER_TYPE + template <> class ColumnImpl<String> : public Column { public: -------------- next part -------------- HTML����������������������������...Download