susumu.yata
null+****@clear*****
Fri Sep 5 18:12:19 JST 2014
susumu.yata 2014-09-05 18:12:19 +0900 (Fri, 05 Sep 2014) New Revision: 87ffdca5c28cbf52d2a6df44c7477d825ad71fe3 https://github.com/groonga/grnxx/commit/87ffdca5c28cbf52d2a6df44c7477d825ad71fe3 Message: Reimplement Array<Record>. The new implementation does not use std::vector. Added files: include/grnxx/array/record.hpp Modified files: include/grnxx/array.hpp lib/grnxx/array.cpp Modified: include/grnxx/array.hpp (+2 -276) =================================================================== --- include/grnxx/array.hpp 2014-09-05 18:10:35 +0900 (68ae1f6) +++ include/grnxx/array.hpp 2014-09-05 18:12:19 +0900 (5d8e030) @@ -1,282 +1,8 @@ #ifndef GRNXX_ARRAY_HPP #define GRNXX_ARRAY_HPP -#include <vector> - -#include "grnxx/types.hpp" - -#include "grnxx/array/primary.hpp" - -namespace grnxx { - -template <> -class ArrayCRef<Record> { - public: - using Value = Record; - - ArrayCRef() = default; - ArrayCRef(const ArrayCRef &) = default; - - ArrayCRef &operator=(const ArrayCRef &) = default; - - bool operator==(ArrayCRef<Record> rhs) const { - return (records_ == rhs.records_) && (size_ == rhs.size_); - } - bool operator!=(ArrayCRef<Record> rhs) const { - return (records_ != rhs.records_) || (size_ != rhs.size_); - } - - ArrayCRef ref(Int offset = 0) const { - return ArrayCRef(records_ + offset, size_ - offset); - } - ArrayCRef ref(Int offset, Int size) const { - return ArrayCRef(records_ + offset, size); - } - - Record get(Int i) const { - return records_[i]; - } - Int get_row_id(Int i) const { - return records_[i].row_id; - } - Float get_score(Int i) const { - return records_[i].score; - } - - Record operator[](Int i) const { - return records_[i]; - } - - Int size() const { - return size_; - } - - private: - const Record *records_; - Int size_; - - ArrayCRef(const Record *records, Int size) - : records_(records), - size_(size) {} - - friend class ArrayRef<Value>; - friend class Array<Value>; -}; - -template <> -class ArrayRef<Record> { - public: - using Value = Record; - - ArrayRef() = default; - ArrayRef(const ArrayRef &) = default; - - ArrayRef &operator=(const ArrayRef &) = default; - - bool operator==(ArrayCRef<Record> rhs) const { - return (records_ == rhs.records_) && (size_ == rhs.size_); - } - bool operator==(ArrayRef<Record> rhs) const { - return (records_ == rhs.records_) && (size_ == rhs.size_); - } - - bool operator!=(ArrayCRef<Record> rhs) const { - return (records_ != rhs.records_) || (size_ != rhs.size_); - } - bool operator!=(ArrayRef<Record> rhs) const { - return (records_ != rhs.records_) || (size_ != rhs.size_); - } - - operator ArrayCRef<Record>() const { - return ref(); - } - - ArrayCRef<Record> ref(Int offset = 0) const { - return ArrayCRef<Record>(records_ + offset, size_ - offset); - } - ArrayCRef<Record> ref(Int offset, Int size) const { - return ArrayCRef<Record>(records_ + offset, size); - } - - ArrayRef ref(Int offset = 0) { - return ArrayRef(records_ + offset, size_ - offset); - } - ArrayRef ref(Int offset, Int size) { - return ArrayRef(records_ + offset, size); - } - - Record get(Int i) const { - return records_[i]; - } - Int get_row_id(Int i) const { - return records_[i].row_id; - } - Float get_score(Int i) const { - return records_[i].score; - } - void set(Int i, Record record) { - records_[i] = record; - } - void set_row_id(Int i, Int row_id) { - records_[i].row_id = row_id; - } - void set_score(Int i, Float score) { - records_[i].score = score; - } - - Record operator[](Int i) const { - return records_[i]; - } - - Int size() const { - return size_; - } - - void swap(Int i, Int j) { - std::swap(records_[i], records_[j]); - } - - private: - Record *records_; - Int size_; - - ArrayRef(Record *records, Int size) : records_(records), size_(size) {} - - friend class Array<Value>; -}; - -template <> -class Array<Record> { - public: - Array() : records_() {} - ~Array() {} - - Array(Array &&array) : records_(std::move(array.records_)) {} - - Array &operator=(Array &&array) { - records_ = std::move(array.records_); - return *this; - } - - operator ArrayCRef<Record>() const { - return ref(); - } - operator ArrayRef<Record>() { - return ref(); - } - - ArrayCRef<Record> ref(Int offset = 0) const { - return ArrayCRef<Record>(records_.data() + offset, size() - offset); - } - ArrayCRef<Record> ref(Int offset, Int size) const { - return ArrayCRef<Record>(records_.data() + offset, size); - } - - ArrayRef<Record> ref(Int offset = 0) { - return ArrayRef<Record>(records_.data() + offset, size() - offset); - } - ArrayRef<Record> ref(Int offset, Int size) { - return ArrayRef<Record>(records_.data() + offset, size); - } - - Record get(Int i) const { - return records_[i]; - } - Int get_row_id(Int i) const { - return records_[i].row_id; - } - Float get_score(Int i) const { - return records_[i].score; - } - void set(Int i, Record record) { - records_[i] = record; - } - void set_row_id(Int i, Int row_id) { - records_[i].row_id = row_id; - } - void set_score(Int i, Float score) { - records_[i].score = score; - } - - Record operator[](Int i) const { - return records_[static_cast<size_t>(i)]; - } - - Record front() const { - return records_.front(); - } - - Record back() const { - return records_.back(); - } - - Int size() const { - return static_cast<Int>(records_.size()); - } - Int capacity() const { - return static_cast<Int>(records_.capacity()); - } - - bool reserve(Error *error, Int new_size) try { - records_.reserve(new_size); - return true; - } catch (...) { - ArrayErrorReporter::report_memory_error(error); - return false; - } - - bool resize(Error *error, Int new_size) try { - records_.resize(new_size); - return true; - } catch (...) { - ArrayErrorReporter::report_memory_error(error); - return false; - } - bool resize(Error *error, Int new_size, Record record) try { - records_.resize(new_size, record); - return true; - } catch (...) { - ArrayErrorReporter::report_memory_error(error); - return false; - } - - bool shrink_to_fit(Error *error) try { - records_.shrink_to_fit(); - return true; - } catch (...) { - ArrayErrorReporter::report_memory_error(error); - return false; - } - - void clear() { - records_.clear(); - } - - void erase(Int i) { - records_.erase(records_.begin() + i); - } - - bool push_back(Error *error, Record record) try { - records_.push_back(record); - return true; - } catch (...) { - ArrayErrorReporter::report_memory_error(error); - return false; - } - void pop_back() { - records_.pop_back(); - } - - void swap(Int i, Int j) { - std::swap(records_[i], records_[j]); - } - - private: - std::vector<Record> records_; -}; - -} // namespace grnxx - #include "grnxx/array/bool.hpp" +#include "grnxx/array/primary.hpp" +#include "grnxx/array/record.hpp" #endif // GRNXX_ARRAY_HPP Added: include/grnxx/array/record.hpp (+313 -0) 100644 =================================================================== --- /dev/null +++ include/grnxx/array/record.hpp 2014-09-05 18:12:19 +0900 (6a8873a) @@ -0,0 +1,313 @@ +#ifndef GRNXX_ARRAY_RECORD_HPP +#define GRNXX_ARRAY_RECORD_HPP + +#include "grnxx/types.hpp" + +namespace grnxx { + +template <typename T> class ArrayCRef; +template <typename T> class ArrayRef; +template <typename T> class Array; + +template <> +class ArrayCRef<Record> { + public: + using Value = Record; + + ArrayCRef() = default; + ArrayCRef(const ArrayCRef &) = default; + + ArrayCRef &operator=(const ArrayCRef &) = default; + + bool operator==(const ArrayCRef<Value> &rhs) const { + return (values_ == rhs.values_) && (size_ == rhs.size_); + } + bool operator!=(const ArrayCRef<Value> &rhs) const { + return (values_ != rhs.values_) || (size_ != rhs.size_); + } + + ArrayCRef ref(Int offset = 0) const { + return ArrayCRef(values_ + offset, size_ - offset); + } + ArrayCRef ref(Int offset, Int size) const { + return ArrayCRef(values_ + offset, size); + } + + const Value &get(Int i) const { + return values_[i]; + } + Int get_row_id(Int i) const { + return values_[i].row_id; + } + Float get_score(Int i) const { + return values_[i].score; + } + + const Value &operator[](Int i) const { + return values_[i]; + } + + Int size() const { + return size_; + } + + private: + const Value *values_; + Int size_; + + ArrayCRef(const Value *values, Int size) : values_(values), size_(size) {} + + friend class ArrayRef<Value>; + friend class Array<Value>; +}; + +template <> +class ArrayRef<Record> { + public: + using Value = Record; + + ArrayRef() = default; + ArrayRef(const ArrayRef &) = default; + + ArrayRef &operator=(const ArrayRef &) = default; + + operator ArrayCRef<Value>() const { + return ref(); + } + + bool operator==(const ArrayCRef<Value> &rhs) const { + return (values_ == rhs.values_) && (size_ == rhs.size_); + } + bool operator==(const ArrayRef<Value> &rhs) const { + return (values_ == rhs.values_) && (size_ == rhs.size_); + } + + bool operator!=(const ArrayCRef<Value> &rhs) const { + return (values_ != rhs.values_) || (size_ != rhs.size_); + } + bool operator!=(const ArrayRef<Value> &rhs) const { + return (values_ != rhs.values_) || (size_ != rhs.size_); + } + + ArrayCRef<Value> ref(Int offset = 0) const { + return ArrayCRef<Value>(values_ + offset, size_ - offset); + } + ArrayCRef<Value> ref(Int offset, Int size) const { + return ArrayCRef<Value>(values_ + offset, size); + } + + ArrayRef ref(Int offset = 0) { + return ArrayRef(values_ + offset, size_ - offset); + } + ArrayRef ref(Int offset, Int size) { + return ArrayRef(values_ + offset, size); + } + + const Value &get(Int i) const { + return values_[i]; + } + Int get_row_id(Int i) const { + return values_[i].row_id; + } + Float get_score(Int i) const { + return values_[i].score; + } + void set(Int i, const Value &value) { + values_[i] = value; + } + void set_row_id(Int i, Int row_id) { + values_[i].row_id = row_id; + } + void set_score(Int i, Float score) { + values_[i].score = score; + } + + const Value &operator[](Int i) const { + return values_[i]; + } + + Int size() const { + return size_; + } + + void swap(Int i, Int j) { + Value temp = values_[i]; + values_[i] = values_[j]; + values_[j] = temp; + } + + private: + Value *values_; + Int size_; + + ArrayRef(Value *values, Int size) : values_(values), size_(size) {} + + friend class Array<Value>; +}; + +template <> +class Array<Record> { + public: + using Value = Record; + + Array() : buf_(), size_(0), capacity_(0) {} + ~Array() {} + + Array(Array &&array) + : buf_(std::move(array.buf_)), + size_(array.size_), + capacity_(array.capacity_) { + array.size_ = 0; + array.capacity_ = 0; + } + + Array &operator=(Array &&array) { + buf_ = std::move(array.buf_); + size_ = array.size_; + capacity_ = array.capacity_; + array.size_ = 0; + array.capacity_ = 0; + return *this; + } + + operator ArrayCRef<Value>() const { + return ref(); + } + + ArrayCRef<Value> ref(Int offset = 0) const { + return ArrayCRef<Value>(data() + offset, size_ - offset); + } + ArrayCRef<Value> ref(Int offset, Int size) const { + return ArrayCRef<Value>(data() + offset, size); + } + + ArrayRef<Value> ref(Int offset = 0) { + return ArrayRef<Value>(data() + offset, size_ - offset); + } + ArrayRef<Value> ref(Int offset, Int size) { + return ArrayRef<Value>(data() + offset, size); + } + + const Value &get(Int i) const { + return data()[i]; + } + Int get_row_id(Int i) const { + return data()[i].row_id; + } + Float get_score(Int i) const { + return data()[i].score; + } + void set(Int i, const Value &value) { + data()[i] = value; + } + void set_row_id(Int i, Int row_id) { + data()[i].row_id = row_id; + } + void set_score(Int i, Float score) { + data()[i].score = score; + } + + const Value &operator[](Int i) const { + return data()[i]; + } + + const Value &front() const { + return *data(); + } + + const Value &back() const { + return data()[size_ - 1]; + } + + Int size() const { + return size_; + } + Int capacity() const { + return capacity_; + } + + bool reserve(Error *error, Int new_size) { + if (new_size <= capacity_) { + return true; + } + return resize_buf(error, new_size); + } + + bool resize(Error *error, Int new_size) { + if (new_size > capacity_) { + if (!resize_buf(error, new_size)) { + return false; + } + } + for (Int i = new_size; i < size_; ++i) { + data()[i].~Value(); + } + for (Int i = size_; i < new_size; ++i) { + new (&data()[i]) Value; + } + size_ = new_size; + return true; + } + bool resize(Error *error, Int new_size, const Value &value) { + if (new_size > capacity_) { + if (!resize_buf(error, new_size)) { + return false; + } + } + for (Int i = new_size; i < size_; ++i) { + data()[i].~Value(); + } + for (Int i = size_; i < new_size; ++i) { + new (&data()[i]) Value(value); + } + size_ = new_size; + return true; + } + + void clear() { + for (Int i = 0; i < size_; ++i) { + data()[i].~Value(); + } + size_ = 0; + } + + bool push_back(Error *error, const Value &value) { + if (size_ == capacity_) { + if (!resize_buf(error, size_ + 1)) { + return false; + } + } + new (&data()[size_]) Value(value); + ++size_; + return true; + } + void pop_back() { + data()[size_ - 1].~Value(); + --size_; + } + + void swap(Int i, Int j) { + Value temp = data()[i]; + data()[i] = data()[j]; + data()[j] = temp; + } + + private: + unique_ptr<char[]> buf_; + Int size_; + Int capacity_; + + Value *data() { + return reinterpret_cast<Value *>(buf_.get()); + } + const Value *data() const { + return reinterpret_cast<const Value *>(buf_.get()); + } + + // Assume new_size > capacity_. + bool resize_buf(Error *error, Int new_size); +}; + +} // namespace grnxx + +#endif // GRNXX_ARRAY_RECORD_HPP Modified: lib/grnxx/array.cpp (+20 -0) =================================================================== --- lib/grnxx/array.cpp 2014-09-05 18:10:35 +0900 (0e34845) +++ lib/grnxx/array.cpp 2014-09-05 18:12:19 +0900 (658c8e3) @@ -27,4 +27,24 @@ bool Array<Bool>::resize_blocks(Error *error, Int new_size) { return true; } +bool Array<Record>::resize_buf(Error *error, Int new_size) { + Int new_capacity = capacity_ * 2; + if (new_size > new_capacity) { + new_capacity = new_size; + } + Int new_buf_size = sizeof(Value) * new_capacity; + unique_ptr<char[]> new_buf(new (nothrow) char[new_buf_size]); + if (!new_buf) { + GRNXX_ERROR_SET(error, NO_MEMORY, "Memory allocation failed"); + return false; + } + Value *new_values = reinterpret_cast<Value *>(new_buf.get()); + for (Int i = 0; i < size_; ++i) { + new (&new_values[i]) Value(std::move(data()[i])); + } + buf_ = std::move(new_buf); + capacity_ = new_capacity; + return true; +} + } // namespace grnxx -------------- next part -------------- HTML����������������������������...Download