[Groonga-commit] groonga/grnxx at 71e3eef [master] Update the interface of Cursor. (#61)

Zurück zum Archiv-Index

susumu.yata null+****@clear*****
Thu Sep 18 16:04:30 JST 2014


susumu.yata	2014-09-18 16:04:30 +0900 (Thu, 18 Sep 2014)

  New Revision: 71e3eef005511dafed52f02697f850884f37415a
  https://github.com/groonga/grnxx/commit/71e3eef005511dafed52f02697f850884f37415a

  Message:
    Update the interface of Cursor. (#61)

  Added files:
    lib/grnxx/cursor.cpp
  Modified files:
    include/grnxx/cursor.hpp
    lib/grnxx/Makefile.am

  Modified: include/grnxx/cursor.hpp (+14 -7)
===================================================================
--- include/grnxx/cursor.hpp    2014-09-17 16:48:23 +0900 (c085589)
+++ include/grnxx/cursor.hpp    2014-09-18 16:04:30 +0900 (8db43d5)
@@ -16,23 +16,30 @@ class Cursor {
 
   // Read the next records.
   //
-  // Reads at most "max_count" records and stores the records into "*records".
+  // Reads at most "max_count" records into "*records".
   //
   // On success, returns the number of records read.
   // On failure, returns -1 and stores error information into "*error" if
   // "error" != nullptr.
-  virtual Int read(Error *error,
-                   Int max_count,
-                   Array<Record> *records) = 0;
+  virtual Int read(Error *error, Int max_count, Array<Record> *records);
+
+  // TODO: should be pure virtual.
+  //
+  // Read the next records.
+  //
+  // Reads at most "records.size()" records into "records".
+  //
+  // On success, returns the number of records read.
+  // On failure, returns -1 and stores error information into "*error" if
+  // "error" != nullptr.
+  virtual Int read(Error *error, ArrayRef<Record> records);
 
   // Read all the remaining records.
   //
   // On success, returns the number of records read.
   // On failure, returns -1 and stores error information into "*error" if
   // "error" != nullptr.
-  virtual Int read_all(Error *error, Array<Record> *records) {
-    return read(error, numeric_limits<Int>::max(), records);
-  }
+  virtual Int read_all(Error *error, Array<Record> *records);
 
  protected:
   const Table *table_;

  Modified: lib/grnxx/Makefile.am (+1 -0)
===================================================================
--- lib/grnxx/Makefile.am    2014-09-17 16:48:23 +0900 (87fa27e)
+++ lib/grnxx/Makefile.am    2014-09-18 16:04:30 +0900 (8d7bf41)
@@ -11,6 +11,7 @@ libgrnxx_la_LDFLAGS = @AM_LTLDFLAGS@
 libgrnxx_la_SOURCES =			\
 	array.cpp			\
 	column.cpp			\
+	cursor.cpp			\
 	db.cpp				\
 	error.cpp			\
 	expression.cpp			\

  Added: lib/grnxx/cursor.cpp (+86 -0) 100644
===================================================================
--- /dev/null
+++ lib/grnxx/cursor.cpp    2014-09-18 16:04:30 +0900 (ae21991)
@@ -0,0 +1,86 @@
+#include "grnxx/cursor.hpp"
+
+namespace grnxx {
+namespace {
+
+constexpr Int CURSOR_BLOCK_SIZE = 1024;
+
+}  // namespace
+
+Int Cursor::read(Error *error, Int max_count, Array<Record> *records) {
+  if (max_count < 0) {
+    GRNXX_ERROR_SET(error, INVALID_ARGUMENT, "Invalid argument");
+    return -1;
+  } else if (max_count == 0) {
+    return read(error, records->ref(0, 0));
+  }
+
+  Int offset = records->size();
+  if (offset > (numeric_limits<Int>::max() - max_count)) {
+    // Reduce "max_count" to avoid overflow.
+    max_count = numeric_limits<Int>::max() - offset;
+  }
+
+  Int next_size = offset + max_count;
+  if (next_size <= records->capacity()) {
+    // There are enough space for requested records.
+    records->resize(nullptr, next_size);
+    Int count = read(error, records->ref(offset, max_count));
+    records->resize(nullptr, offset + ((count != -1) ? count : 0));
+    return count;
+  }
+
+  // Read the first block.
+  Int block_size = max_count;
+  if (block_size > CURSOR_BLOCK_SIZE) {
+    block_size = CURSOR_BLOCK_SIZE;
+  }
+  if (!records->resize(error, offset + block_size)) {
+    return -1;
+  }
+  Int count = read(error, records->ref(offset, block_size));
+  if (count != block_size) {
+    records->resize(nullptr, offset + ((count != -1) ? count : 0));
+    if (count <= 0) {
+      return count;
+    }
+  }
+
+  // Read the remaining blocks.
+  while (count < max_count) {
+    block_size = max_count - count;
+    if (block_size > CURSOR_BLOCK_SIZE) {
+      block_size = CURSOR_BLOCK_SIZE;
+    }
+    Int this_offset = offset + count;
+    if (!records->resize(error, this_offset + block_size)) {
+      return count;
+    }
+    Int this_count = read(error, records->ref(this_offset, block_size));
+    if (this_count != block_size) {
+      records->resize(nullptr,
+                      this_offset + ((this_count != -1) ? this_count : 0));
+      if (this_count <= 0) {
+        return count;
+      }
+    }
+    count += this_count;
+  }
+  return count;
+}
+
+// TODO: To be removed!
+Int Cursor::read(Error *, ArrayRef<Record>) {
+  return -1;
+}
+
+Int Cursor::read_all(Error *error, Array<Record> *records) {
+  Int total_count = 0;
+  Int count;
+  while ((count = read(error, numeric_limits<Int>::max(), records)) > 0) {
+    total_count += count;
+  }
+  return (count == 0) ? total_count : count;
+}
+
+}  // namespace grnxx
-------------- next part --------------
HTML����������������������������...
Download 



More information about the Groonga-commit mailing list
Zurück zum Archiv-Index