1
0
Fork 0

Former JsonCursor now uses QueryResult and contains the TRX context for continuuos reads

This commit is contained in:
Michael Hackstein 2016-04-19 14:32:23 +02:00
parent 36e608a5fd
commit be118b1b80
8 changed files with 67 additions and 68 deletions

View File

@ -541,10 +541,10 @@ QueryResult Query::execute(QueryRegistry* registry) {
}
}
QueryResult res = prepare(registry);
QueryResult result = prepare(registry);
if (res.code != TRI_ERROR_NO_ERROR) {
return res;
if (result.code != TRI_ERROR_NO_ERROR) {
return result;
}
if (_queryString == nullptr) {
@ -631,11 +631,12 @@ QueryResult Query::execute(QueryRegistry* registry) {
auto stats = std::make_shared<VPackBuilder>();
_engine->_stats.toVelocyPack(*(stats.get()));
result.context = _trx->transactionContext();
cleanupPlanAndEngine(TRI_ERROR_NO_ERROR);
enterState(FINALIZATION);
QueryResult result(TRI_ERROR_NO_ERROR);
result.warnings = warningsToVelocyPack();
result.result = resultBuilder;
result.stats = stats;
@ -700,10 +701,10 @@ QueryResultV8 Query::executeV8(v8::Isolate* isolate, QueryRegistry* registry) {
}
}
QueryResultV8 res = prepare(registry);
QueryResultV8 result = prepare(registry);
if (res.code != TRI_ERROR_NO_ERROR) {
return res;
if (result.code != TRI_ERROR_NO_ERROR) {
return result;
}
work.reset(new AqlWorkStack(_vocbase, _id, _queryString, _queryLength));
@ -715,7 +716,6 @@ QueryResultV8 Query::executeV8(v8::Isolate* isolate, QueryRegistry* registry) {
useQueryCache = false;
}
QueryResultV8 result(TRI_ERROR_NO_ERROR);
result.result = v8::Array::New(isolate);
// this is the RegisterId our results can be found in
@ -781,6 +781,8 @@ QueryResultV8 Query::executeV8(v8::Isolate* isolate, QueryRegistry* registry) {
auto stats = std::make_shared<VPackBuilder>();
_engine->_stats.toVelocyPack(*(stats.get()));
result.context = _trx->transactionContext();
cleanupPlanAndEngine(TRI_ERROR_NO_ERROR);
enterState(FINALIZATION);

View File

@ -30,23 +30,14 @@ namespace arangodb {
namespace velocypack {
class Builder;
}
class TransactionContext;
namespace aql {
struct QueryResult {
QueryResult& operator=(QueryResult const& other) = delete;
QueryResult(QueryResult&& other) {
code = other.code;
cached = other.cached;
details = other.details;
warnings.swap(other.warnings);
result.swap(other.result);
stats.swap(other.stats);
profile.swap(other.profile);
bindParameters = other.bindParameters;
collectionNames = other.collectionNames;
}
QueryResult(QueryResult&& other) = default;
QueryResult(int code, std::string const& details)
: code(code),
@ -54,7 +45,8 @@ struct QueryResult {
details(details),
warnings(nullptr),
result(nullptr),
profile(nullptr) {}
profile(nullptr),
context(nullptr) {}
explicit QueryResult(int code) : QueryResult(code, "") {}
@ -71,6 +63,7 @@ struct QueryResult {
std::shared_ptr<arangodb::velocypack::Builder> result;
std::shared_ptr<arangodb::velocypack::Builder> stats;
std::shared_ptr<arangodb::velocypack::Builder> profile;
std::shared_ptr<arangodb::TransactionContext> context;
};
}
}

View File

@ -177,10 +177,9 @@ void RestCursorHandler::processQuery(VPackSlice const& slice) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
}
auto transactionContext = std::make_shared<StandaloneTransactionContext>(_vocbase);
arangodb::basics::VPackStringBufferAdapter bufferAdapter(
_response->body().stringBuffer());
VPackDumper dumper(&bufferAdapter, transactionContext->getVPackOptions());
VPackDumper dumper(&bufferAdapter, queryResult.context->getVPackOptions());
dumper.dump(result.slice());
return;
}
@ -195,8 +194,8 @@ void RestCursorHandler::processQuery(VPackSlice const& slice) {
opts, "count", false);
// steal the query result, cursor will take over the ownership
arangodb::JsonCursor* cursor = cursors->createFromVelocyPack(
queryResult.result, batchSize, extra, ttl, count, queryResult.cached);
arangodb::VelocyPackCursor* cursor = cursors->createFromQueryResult(
std::move(queryResult), batchSize, extra, ttl, count);
try {
_response->body().appendChar('{');

View File

@ -22,7 +22,6 @@
////////////////////////////////////////////////////////////////////////////////
#include "Cursor.h"
#include "Basics/JsonHelper.h"
#include "Basics/VelocyPackHelper.h"
#include "Basics/VPackStringBufferAdapter.h"
#include "Utils/CollectionExport.h"
@ -63,20 +62,20 @@ VPackSlice Cursor::extra() const {
return _extra->slice();
}
JsonCursor::JsonCursor(TRI_vocbase_t* vocbase, CursorId id,
std::shared_ptr<VPackBuilder> json, size_t batchSize,
std::shared_ptr<VPackBuilder> extra, double ttl,
bool hasCount, bool cached)
VelocyPackCursor::VelocyPackCursor(TRI_vocbase_t* vocbase, CursorId id,
aql::QueryResult&& result, size_t batchSize,
std::shared_ptr<VPackBuilder> extra,
double ttl, bool hasCount)
: Cursor(id, batchSize, extra, ttl, hasCount),
_vocbase(vocbase),
_json(json),
_size(json->slice().length()),
_cached(cached) {
TRI_ASSERT(json->slice().isArray());
_result(std::move(result)),
_size(result.result->slice().length()),
_cached(result.cached) {
TRI_ASSERT(result.result->slice().isArray());
TRI_UseVocBase(vocbase);
}
JsonCursor::~JsonCursor() {
VelocyPackCursor::~VelocyPackCursor() {
freeJson();
TRI_ReleaseVocBase(_vocbase);
@ -86,7 +85,7 @@ JsonCursor::~JsonCursor() {
/// @brief check whether the cursor contains more data
////////////////////////////////////////////////////////////////////////////////
bool JsonCursor::hasNext() {
bool VelocyPackCursor::hasNext() {
if (_position < _size) {
return true;
}
@ -99,10 +98,10 @@ bool JsonCursor::hasNext() {
/// @brief return the next element
////////////////////////////////////////////////////////////////////////////////
VPackSlice JsonCursor::next() {
TRI_ASSERT(_json != nullptr);
VPackSlice VelocyPackCursor::next() {
TRI_ASSERT(_result.result != nullptr);
TRI_ASSERT(_position < _size);
VPackSlice slice = _json->slice();
VPackSlice slice = _result.result->slice();
return slice.at(_position++);
}
@ -110,13 +109,13 @@ VPackSlice JsonCursor::next() {
/// @brief return the cursor size
////////////////////////////////////////////////////////////////////////////////
size_t JsonCursor::count() const { return _size; }
size_t VelocyPackCursor::count() const { return _size; }
////////////////////////////////////////////////////////////////////////////////
/// @brief dump the cursor contents into a string buffer
////////////////////////////////////////////////////////////////////////////////
void JsonCursor::dump(arangodb::basics::StringBuffer& buffer) {
void VelocyPackCursor::dump(arangodb::basics::StringBuffer& buffer) {
buffer.appendText("\"result\":[");
size_t const n = batchSize();
@ -135,6 +134,9 @@ void JsonCursor::dump(arangodb::basics::StringBuffer& buffer) {
}
}
arangodb::basics::VPackStringBufferAdapter bufferAdapter(
buffer.stringBuffer());
VPackDumper dumper(&bufferAdapter, transactionContext->getVPackOptions());
for (size_t i = 0; i < n; ++i) {
if (!hasNext()) {
break;
@ -149,9 +151,6 @@ void JsonCursor::dump(arangodb::basics::StringBuffer& buffer) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
}
arangodb::basics::VPackStringBufferAdapter bufferAdapter(
buffer.stringBuffer());
VPackDumper dumper(&bufferAdapter, transactionContext->getVPackOptions());
try {
dumper.dump(row);
} catch (...) {
@ -198,9 +197,7 @@ void JsonCursor::dump(arangodb::basics::StringBuffer& buffer) {
/// @brief free the internals
////////////////////////////////////////////////////////////////////////////////
void JsonCursor::freeJson() {
_json = nullptr;
void VelocyPackCursor::freeJson() {
_isDeleted = true;
}

View File

@ -26,6 +26,7 @@
#include "Basics/Common.h"
#include "Basics/StringBuffer.h"
#include "Aql/QueryResult.h"
#include "VocBase/voc-types.h"
struct TRI_vocbase_t;
@ -107,14 +108,13 @@ class Cursor {
bool _isUsed;
};
class JsonCursor : public Cursor {
class VelocyPackCursor : public Cursor {
public:
JsonCursor(TRI_vocbase_t*, CursorId,
std::shared_ptr<arangodb::velocypack::Builder>, size_t,
std::shared_ptr<arangodb::velocypack::Builder>, double, bool,
bool);
VelocyPackCursor(TRI_vocbase_t*, CursorId, aql::QueryResult&&, size_t,
std::shared_ptr<arangodb::velocypack::Builder>, double,
bool);
~JsonCursor();
~VelocyPackCursor();
public:
bool hasNext() override final;
@ -130,7 +130,7 @@ class JsonCursor : public Cursor {
private:
TRI_vocbase_t* _vocbase;
std::shared_ptr<arangodb::velocypack::Builder> _json;
aql::QueryResult _result;
size_t const _size;
bool _cached;
};

View File

@ -91,17 +91,15 @@ CursorRepository::~CursorRepository() {
/// the cursor will take ownership of both json and extra
////////////////////////////////////////////////////////////////////////////////
JsonCursor* CursorRepository::createFromVelocyPack(
std::shared_ptr<VPackBuilder> json, size_t batchSize,
std::shared_ptr<VPackBuilder> extra, double ttl, bool count, bool cached) {
TRI_ASSERT(json != nullptr);
VelocyPackCursor* CursorRepository::createFromQueryResult(
aql::QueryResult&& result, size_t batchSize, std::shared_ptr<VPackBuilder> extra,
double ttl, bool count) {
TRI_ASSERT(result.result != nullptr);
CursorId const id = TRI_NewTickServer();
arangodb::JsonCursor* cursor = nullptr;
cursor = new arangodb::JsonCursor(_vocbase, id, json, batchSize, extra, ttl,
count, cached);
arangodb::VelocyPackCursor* cursor = new arangodb::VelocyPackCursor(
_vocbase, id, std::move(result), batchSize, extra, ttl, count);
cursor->use();
try {

View File

@ -36,6 +36,10 @@ namespace velocypack {
class Builder;
}
namespace aql {
struct QueryResult;
}
class CollectionExport;
class CursorRepository {
@ -60,9 +64,9 @@ class CursorRepository {
/// the cursor will retain a shared pointer of both json and extra
//////////////////////////////////////////////////////////////////////////////
JsonCursor* createFromVelocyPack(
std::shared_ptr<arangodb::velocypack::Builder>, size_t,
std::shared_ptr<arangodb::velocypack::Builder>, double, bool, bool);
VelocyPackCursor* createFromQueryResult(
aql::QueryResult&&, size_t, std::shared_ptr<arangodb::velocypack::Builder>,
double, bool);
//////////////////////////////////////////////////////////////////////////////
/// @brief creates a cursor and stores it in the registry

View File

@ -25,6 +25,7 @@
#include "Basics/conversions.h"
#include "Utils/Cursor.h"
#include "Utils/CursorRepository.h"
#include "Utils/StandaloneTransactionContext.h"
#include "V8/v8-conv.h"
#include "V8/v8-vpack.h"
#include "V8Server/v8-voccursor.h"
@ -88,9 +89,14 @@ static void JS_CreateCursor(v8::FunctionCallbackInfo<v8::Value> const& args) {
auto cursors =
static_cast<arangodb::CursorRepository*>(vocbase->_cursorRepository);
arangodb::aql::QueryResult result(TRI_ERROR_NO_ERROR);
result.result = builder;
result.cached = false;
result.context = std::make_shared<arangodb::StandaloneTransactionContext>(vocbase);
try {
arangodb::Cursor* cursor = cursors->createFromVelocyPack(
builder, static_cast<size_t>(batchSize), nullptr, ttl, true, false);
arangodb::Cursor* cursor = cursors->createFromQueryResult(
std::move(result), static_cast<size_t>(batchSize), nullptr, ttl, true);
TRI_ASSERT(cursor != nullptr);
cursors->release(cursor);