[Groonga-commit] groonga/grnxx at 87ffdca [master] Reimplement Array<Record>.

Back to archive index

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 



More information about the Groonga-commit mailing list
Back to archive index