Skip to content

Commit

Permalink
Update the interface of Cursor. (#61)
Browse files Browse the repository at this point in the history
  • Loading branch information
s-yata committed Sep 18, 2014
1 parent f500fa9 commit 71e3eef
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 7 deletions.
21 changes: 14 additions & 7 deletions include/grnxx/cursor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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_;
Expand Down
1 change: 1 addition & 0 deletions lib/grnxx/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ libgrnxx_la_LDFLAGS = @AM_LTLDFLAGS@
libgrnxx_la_SOURCES = \
array.cpp \
column.cpp \
cursor.cpp \
db.cpp \
error.cpp \
expression.cpp \
Expand Down
86 changes: 86 additions & 0 deletions lib/grnxx/cursor.cpp
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 71e3eef

Please sign in to comment.