1
0
Fork 0

Merge branch 'spdvpk' of ssh://github.com/ArangoDB/ArangoDB into spdvpk

This commit is contained in:
Max Neunhoeffer 2016-03-08 11:21:09 +01:00
commit bd7ccc1444
9 changed files with 73 additions and 414 deletions

View File

@ -327,10 +327,39 @@ class Slice {
return last;
}
// look for the specified attribute path inside an Object
// returns a Slice(ValueType::None) if not found
Slice get(std::vector<char const*> const& attributes) const {
size_t const n = attributes.size();
if (n == 0) {
throw Exception(Exception::InvalidAttributePath);
}
// use ourselves as the starting point
Slice last = Slice(start());
for (size_t i = 0; i < attributes.size(); ++i) {
// fetch subattribute
last = last.get(attributes[i]);
// abort as early as possible
if (last.isNone() || (i + 1 < n && !last.isObject())) {
return Slice();
}
}
return last;
}
// look for the specified attribute inside an Object
// returns a Slice(ValueType::None) if not found
Slice get(std::string const& attribute) const;
// look for the specified attribute inside an Object
// returns a Slice(ValueType::None) if not found
Slice get(char const* attribute) const {
return get(std::string(attribute));
}
Slice operator[](std::string const& attribute) const {
return get(attribute);
}

View File

@ -22,16 +22,15 @@
////////////////////////////////////////////////////////////////////////////////
#include "AttributeAccessor.h"
#include "Basics/JsonHelper.h"
#include "Aql/AqlItemBlock.h"
#include "Aql/Variable.h"
#include "Basics/StringBuffer.h"
#include "Basics/json.h"
#include "VocBase/document-collection.h"
#include "VocBase/shaped-json.h"
#include "VocBase/VocShaper.h"
#include "Utils/AqlTransaction.h"
#include <velocypack/Slice.h>
#include <velocypack/velocypack-aliases.h>
using namespace arangodb::aql;
using Json = arangodb::basics::Json;
////////////////////////////////////////////////////////////////////////////////
/// @brief create the accessor
@ -41,38 +40,8 @@ AttributeAccessor::AttributeAccessor(
std::vector<char const*> const& attributeParts, Variable const* variable)
: _attributeParts(attributeParts),
_combinedName(),
_variable(variable),
_buffer(TRI_UNKNOWN_MEM_ZONE),
_shaper(nullptr),
_pid(0),
_nameCache({"", 0}),
_attributeType(ATTRIBUTE_TYPE_REGULAR) {
_variable(variable) {
TRI_ASSERT(_variable != nullptr);
if (_attributeParts.size() == 1) {
char const* n = _attributeParts[0];
if (strcmp(n, TRI_VOC_ATTRIBUTE_KEY) == 0) {
_attributeType = ATTRIBUTE_TYPE_KEY;
} else if (strcmp(n, TRI_VOC_ATTRIBUTE_REV) == 0) {
_attributeType = ATTRIBUTE_TYPE_REV;
} else if (strcmp(n, TRI_VOC_ATTRIBUTE_ID) == 0) {
_attributeType = ATTRIBUTE_TYPE_ID;
} else if (strcmp(n, TRI_VOC_ATTRIBUTE_FROM) == 0) {
_attributeType = ATTRIBUTE_TYPE_FROM;
} else if (strcmp(n, TRI_VOC_ATTRIBUTE_TO) == 0) {
_attributeType = ATTRIBUTE_TYPE_TO;
}
}
if (_attributeType == ATTRIBUTE_TYPE_REGULAR) {
for (auto const& it : _attributeParts) {
if (!_combinedName.empty()) {
_combinedName.push_back('.');
}
_combinedName.append(it);
}
}
}
////////////////////////////////////////////////////////////////////////////////
@ -96,206 +65,15 @@ AqlValue AttributeAccessor::get(arangodb::AqlTransaction* trx,
auto& result = argv->getValueReference(startPos, regs[i]);
// extract the attribute
if (result.isShaped()) {
switch (_attributeType) {
case ATTRIBUTE_TYPE_KEY: {
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE,
TRI_EXTRACT_MARKER_KEY(result._marker)));
}
case ATTRIBUTE_TYPE_REV: {
return extractRev(result);
}
case ATTRIBUTE_TYPE_ID: {
TRI_document_collection_t const* collection =
argv->getDocumentCollection(regs[i]);
return extractId(result, trx, collection);
}
case ATTRIBUTE_TYPE_FROM: {
return extractFrom(result, trx);
}
case ATTRIBUTE_TYPE_TO: {
return extractTo(result, trx);
}
case ATTRIBUTE_TYPE_REGULAR:
default: {
TRI_document_collection_t const* collection =
argv->getDocumentCollection(regs[i]);
return extractRegular(result, trx, collection);
}
}
} else if (result.isJson()) {
TRI_json_t const* json = result._json->json();
size_t const n = _attributeParts.size();
size_t i = 0;
while (TRI_IsObjectJson(json)) {
TRI_ASSERT(i < n);
json = TRI_LookupObjectJson(json, _attributeParts[i]);
if (json == nullptr) {
break;
}
++i;
if (i == n) {
// reached the end
std::unique_ptr<TRI_json_t> copy(
TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, json));
if (copy == nullptr) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
}
auto result = new Json(TRI_UNKNOWN_MEM_ZONE, copy.get());
copy.release();
return AqlValue(result);
}
}
// fall-through intentional
}
break;
VPackSlice const slice;
#warning TODO: fill slice from AqlValue (result)
VPackSlice extracted = slice.get(_attributeParts);
#warning TODO: build result from extracted
return AqlValue(new arangodb::basics::Json(arangodb::basics::Json::Null));
}
// fall-through intentional
}
return AqlValue(new Json(Json::Null));
return AqlValue(new arangodb::basics::Json(arangodb::basics::Json::Null));
}
////////////////////////////////////////////////////////////////////////////////
/// @brief extract the _rev attribute from a ShapedJson marker
////////////////////////////////////////////////////////////////////////////////
AqlValue AttributeAccessor::extractRev(AqlValue const& src) {
_buffer.reset();
_buffer.appendInteger(TRI_EXTRACT_MARKER_RID(src._marker));
auto json = new Json(TRI_UNKNOWN_MEM_ZONE, _buffer.c_str(), _buffer.length());
return AqlValue(json);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief extract the _id attribute from a ShapedJson marker
////////////////////////////////////////////////////////////////////////////////
AqlValue AttributeAccessor::extractId(
AqlValue const& src, arangodb::AqlTransaction* trx,
TRI_document_collection_t const* document) {
if (_nameCache.value.empty()) {
_nameCache.value = trx->resolver()->getCollectionName(document->_info.id());
}
_buffer.reset();
_buffer.appendText(_nameCache.value);
_buffer.appendChar('/');
_buffer.appendText(TRI_EXTRACT_MARKER_KEY(src._marker));
auto json = new Json(TRI_UNKNOWN_MEM_ZONE, _buffer.c_str(), _buffer.length());
return AqlValue(json);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief extract the _from attribute from a ShapedJson marker
////////////////////////////////////////////////////////////////////////////////
AqlValue AttributeAccessor::extractFrom(AqlValue const& src,
arangodb::AqlTransaction* trx) {
// TODO vpack
if (src._marker->getType() != TRI_DOC_MARKER_KEY_EDGE) {
return AqlValue(new Json(Json::Null));
}
auto cid = TRI_EXTRACT_MARKER_FROM_CID(src._marker);
if (_nameCache.value.empty() || _nameCache.cid != cid) {
_nameCache.cid = cid;
_nameCache.value = trx->resolver()->getCollectionNameCluster(cid);
}
_buffer.reset();
_buffer.appendText(_nameCache.value);
_buffer.appendChar('/');
_buffer.appendText(TRI_EXTRACT_MARKER_FROM_KEY(src._marker));
auto json = new Json(TRI_UNKNOWN_MEM_ZONE, _buffer.c_str(), _buffer.length());
return AqlValue(json);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief extract the _to attribute from a ShapedJson marker
////////////////////////////////////////////////////////////////////////////////
AqlValue AttributeAccessor::extractTo(AqlValue const& src,
arangodb::AqlTransaction* trx) {
// TODO vpack
if (src._marker->getType() != TRI_DOC_MARKER_KEY_EDGE) {
return AqlValue(new Json(Json::Null));
}
auto cid = TRI_EXTRACT_MARKER_TO_CID(src._marker);
if (_nameCache.value.empty() || _nameCache.cid != cid) {
_nameCache.cid = cid;
_nameCache.value = trx->resolver()->getCollectionNameCluster(cid);
}
_buffer.reset();
_buffer.appendText(_nameCache.value);
_buffer.appendChar('/');
_buffer.appendText(TRI_EXTRACT_MARKER_TO_KEY(src._marker));
auto json = new Json(TRI_UNKNOWN_MEM_ZONE, _buffer.c_str(), _buffer.length());
return AqlValue(json);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief extract any other attribute from a ShapedJson marker
////////////////////////////////////////////////////////////////////////////////
AqlValue AttributeAccessor::extractRegular(
AqlValue const& src, arangodb::AqlTransaction* trx,
TRI_document_collection_t const* document) {
if (_shaper == nullptr) {
_shaper = document->getShaper();
_pid = _shaper->lookupAttributePathByName(_combinedName.c_str());
}
if (_pid != 0) {
// attribute exists
TRI_ASSERT(_shaper != nullptr);
TRI_shaped_json_t shapedJson;
TRI_EXTRACT_SHAPED_JSON_MARKER(shapedJson, src._marker);
TRI_shaped_json_t json;
TRI_shape_t const* shape;
bool ok = _shaper->extractShapedJson(&shapedJson, 0, _pid, &json, &shape);
if (ok && shape != nullptr) {
std::unique_ptr<TRI_json_t> extracted(TRI_JsonShapedJson(_shaper, &json));
if (extracted == nullptr) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
}
auto j = new Json(TRI_UNKNOWN_MEM_ZONE, extracted.get());
extracted.release();
return AqlValue(j);
}
}
return AqlValue(new Json(Json::Null));
}

View File

@ -27,17 +27,12 @@
#include "Basics/Common.h"
#include "Aql/AqlValue.h"
#include "Aql/types.h"
#include "Basics/StringBuffer.h"
#include "Utils/AqlTransaction.h"
#include "VocBase/shaped-json.h"
struct TRI_document_collection_t;
class VocShaper;
namespace arangodb {
namespace aql {
class AqlItemBlock;
class AqlTransaction;
struct Variable;
////////////////////////////////////////////////////////////////////////////////
@ -45,15 +40,6 @@ struct Variable;
////////////////////////////////////////////////////////////////////////////////
class AttributeAccessor {
enum AttributeType {
ATTRIBUTE_TYPE_KEY,
ATTRIBUTE_TYPE_REV,
ATTRIBUTE_TYPE_ID,
ATTRIBUTE_TYPE_FROM,
ATTRIBUTE_TYPE_TO,
ATTRIBUTE_TYPE_REGULAR
};
public:
AttributeAccessor(std::vector<char const*> const&, Variable const*);
@ -67,39 +53,6 @@ class AttributeAccessor {
std::vector<Variable const*> const&,
std::vector<RegisterId> const&);
private:
//////////////////////////////////////////////////////////////////////////////
/// @brief extract the _rev attribute from a ShapedJson marker
//////////////////////////////////////////////////////////////////////////////
AqlValue extractRev(AqlValue const&);
//////////////////////////////////////////////////////////////////////////////
/// @brief extract the _id attribute from a ShapedJson marker
//////////////////////////////////////////////////////////////////////////////
AqlValue extractId(AqlValue const&, arangodb::AqlTransaction*,
struct TRI_document_collection_t const*);
//////////////////////////////////////////////////////////////////////////////
/// @brief extract the _from attribute from a ShapedJson marker
//////////////////////////////////////////////////////////////////////////////
AqlValue extractFrom(AqlValue const&, arangodb::AqlTransaction*);
//////////////////////////////////////////////////////////////////////////////
/// @brief extract the _to attribute from a ShapedJson marker
//////////////////////////////////////////////////////////////////////////////
AqlValue extractTo(AqlValue const&, arangodb::AqlTransaction*);
//////////////////////////////////////////////////////////////////////////////
/// @brief extract any other attribute from a ShapedJson marker
//////////////////////////////////////////////////////////////////////////////
AqlValue extractRegular(AqlValue const&, arangodb::AqlTransaction*,
struct TRI_document_collection_t const*);
private:
//////////////////////////////////////////////////////////////////////////////
/// @brief the attribute names vector (e.g. [ "a", "b", "c" ] for a.b.c)
@ -119,38 +72,6 @@ class AttributeAccessor {
Variable const* _variable;
//////////////////////////////////////////////////////////////////////////////
/// @brief buffer for temporary strings
//////////////////////////////////////////////////////////////////////////////
arangodb::basics::StringBuffer _buffer;
//////////////////////////////////////////////////////////////////////////////
/// @brief shaper
//////////////////////////////////////////////////////////////////////////////
VocShaper* _shaper;
//////////////////////////////////////////////////////////////////////////////
/// @brief attribute path id cache for shapes
//////////////////////////////////////////////////////////////////////////////
TRI_shape_pid_t _pid;
//////////////////////////////////////////////////////////////////////////////
/// @brief collection name lookup cache
//////////////////////////////////////////////////////////////////////////////
struct {
std::string value;
TRI_voc_cid_t cid;
} _nameCache;
//////////////////////////////////////////////////////////////////////////////
/// @brief attribute type (to save repeated strcmp calls)
//////////////////////////////////////////////////////////////////////////////
AttributeType _attributeType;
};
} // namespace arangodb::aql

View File

@ -42,6 +42,7 @@
#include "Utils/StandaloneTransactionContext.h"
#include "Utils/V8TransactionContext.h"
#include "V8/v8-conv.h"
#include "V8/v8-vpack.h"
#include "V8Server/ApplicationV8.h"
#include "VocBase/vocbase.h"
#include "VocBase/Graphs.h"
@ -617,7 +618,7 @@ QueryResult Query::execute(QueryRegistry* registry) {
warningsToVelocyPack(tmp);
tmp.close();
res.warnings = arangodb::basics::VelocyPackHelper::velocyPackToJson(tmp.slice().get("warnings"));
res.json = TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, cacheEntry->_queryResult);
res.json = arangodb::basics::VelocyPackHelper::velocyPackToJson(cacheEntry->_queryResult->slice());
res.cached = true;
if (res.json == nullptr) {
@ -680,20 +681,18 @@ QueryResult Query::execute(QueryRegistry* registry) {
if (_warnings.empty()) {
// finally store the generated result in the query cache
std::unique_ptr<TRI_json_t> copy(
TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, jsonResult.json()));
std::shared_ptr<VPackBuilder> copy(arangodb::basics::JsonHelper::toVelocyPack(jsonResult.json()));
if (copy == nullptr) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
}
auto result = QueryCache::instance()->store(
_vocbase, queryStringHash, _queryString, _queryLength, copy.get(),
_vocbase, queryStringHash, _queryString, _queryLength, copy,
_trx->collectionNames());
if (result != nullptr) {
// result now belongs to cache
copy.release();
if (result == nullptr) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
}
}
} else {
@ -789,8 +788,7 @@ QueryResultV8 Query::executeV8(v8::Isolate* isolate, QueryRegistry* registry) {
if (cacheEntry != nullptr) {
// got a result from the query cache
QueryResultV8 res(TRI_ERROR_NO_ERROR);
res.result = v8::Handle<v8::Array>::Cast(
TRI_ObjectJson(isolate, cacheEntry->_queryResult));
res.result = v8::Handle<v8::Array>::Cast(TRI_VPackToV8(isolate, cacheEntry->_queryResult->slice()));
res.cached = true;
return res;
}
@ -821,12 +819,8 @@ QueryResultV8 Query::executeV8(v8::Isolate* isolate, QueryRegistry* registry) {
try {
if (useQueryCache) {
// iterate over result, return it and store it in query cache
std::unique_ptr<TRI_json_t> cacheResult(
TRI_CreateArrayJson(TRI_UNKNOWN_MEM_ZONE));
if (cacheResult == nullptr) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
}
auto builder = std::make_shared<VPackBuilder>();
builder->openArray();
uint32_t j = 0;
while (nullptr != (value = _engine->getSome(
@ -842,20 +836,24 @@ QueryResultV8 Query::executeV8(v8::Isolate* isolate, QueryRegistry* registry) {
result.result->Set(j++, val.toV8(isolate, _trx, doc));
auto json = val.toJson(_trx, doc, true);
TRI_PushBack3ArrayJson(TRI_UNKNOWN_MEM_ZONE, cacheResult.get(),
json.steal());
int res = arangodb::basics::JsonHelper::toVelocyPack(json.json(), *(builder.get()));
if (res != TRI_ERROR_NO_ERROR) {
delete value;
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
}
}
}
delete value;
value = nullptr;
}
builder->close();
if (_warnings.empty()) {
// finally store the generated result in the query cache
QueryCache::instance()->store(_vocbase, queryStringHash, _queryString,
_queryLength, cacheResult.get(),
_trx->collectionNames());
cacheResult.release();
_queryLength, builder, _trx->collectionNames());
}
} else {
// iterate over result and return it

View File

@ -23,7 +23,6 @@
#include "Aql/QueryCache.h"
#include "Basics/fasthash.h"
#include "Basics/json.h"
#include "Basics/Exceptions.h"
#include "Basics/MutexLocker.h"
#include "Basics/ReadLocker.h"
@ -60,7 +59,7 @@ static std::atomic<arangodb::aql::QueryCacheMode> Mode(CACHE_ON_DEMAND);
QueryCacheResultEntry::QueryCacheResultEntry(
uint64_t hash, char const* queryString, size_t queryStringLength,
TRI_json_t* queryResult, std::vector<std::string> const& collections)
std::shared_ptr<VPackBuilder> queryResult, std::vector<std::string> const& collections)
: _hash(hash),
_queryString(nullptr),
_queryStringLength(queryStringLength),
@ -83,7 +82,6 @@ QueryCacheResultEntry::QueryCacheResultEntry(
////////////////////////////////////////////////////////////////////////////////
QueryCacheResultEntry::~QueryCacheResultEntry() {
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, _queryResult);
TRI_FreeString(TRI_UNKNOWN_MEM_ZONE, _queryString);
}
@ -393,12 +391,13 @@ QueryCache::~QueryCache() {
VPackBuilder QueryCache::properties() {
MUTEX_LOCKER(mutexLocker, _propertiesLock);
VPackBuilder json;
json.add(VPackValue(VPackValueType::Object));
json.add("mode", VPackValue(modeString(mode())));
json.add("maxResults", VPackValue(MaxResults));
json.close();
return json;
VPackBuilder builder;
builder.openObject();
builder.add("mode", VPackValue(modeString(mode())));
builder.add("maxResults", VPackValue(MaxResults));
builder.close();
return builder;
}
////////////////////////////////////////////////////////////////////////////////
@ -486,9 +485,9 @@ QueryCacheResultEntry* QueryCache::lookup(TRI_vocbase_t* vocbase, uint64_t hash,
QueryCacheResultEntry* QueryCache::store(
TRI_vocbase_t* vocbase, uint64_t hash, char const* queryString,
size_t queryStringLength, TRI_json_t* result,
size_t queryStringLength, std::shared_ptr<VPackBuilder> result,
std::vector<std::string> const& collections) {
if (!TRI_IsArrayJson(result)) {
if (!result->slice().isArray()) {
return nullptr;
}

View File

@ -25,11 +25,9 @@
#define ARANGOD_AQL_QUERY_CACHE_H 1
#include "Basics/Common.h"
#include "Basics/JsonHelper.h"
#include "Basics/Mutex.h"
#include "Basics/ReadWriteLock.h"
struct TRI_json_t;
struct TRI_vocbase_t;
namespace arangodb {
@ -47,7 +45,7 @@ enum QueryCacheMode { CACHE_ALWAYS_OFF, CACHE_ALWAYS_ON, CACHE_ON_DEMAND };
struct QueryCacheResultEntry {
QueryCacheResultEntry() = delete;
QueryCacheResultEntry(uint64_t, char const*, size_t, struct TRI_json_t*,
QueryCacheResultEntry(uint64_t, char const*, size_t, std::shared_ptr<arangodb::velocypack::Builder>,
std::vector<std::string> const&);
~QueryCacheResultEntry();
@ -73,7 +71,7 @@ struct QueryCacheResultEntry {
uint64_t const _hash;
char* _queryString;
size_t const _queryStringLength;
struct TRI_json_t* _queryResult;
std::shared_ptr<arangodb::velocypack::Builder> _queryResult;
std::vector<std::string> const _collections;
QueryCacheResultEntry* _prev;
QueryCacheResultEntry* _next;
@ -273,7 +271,7 @@ class QueryCache {
//////////////////////////////////////////////////////////////////////////////
QueryCacheResultEntry* store(TRI_vocbase_t*, uint64_t, char const*, size_t,
struct TRI_json_t*,
std::shared_ptr<arangodb::velocypack::Builder>,
std::vector<std::string> const&);
//////////////////////////////////////////////////////////////////////////////

View File

@ -24,11 +24,8 @@
#include "v8-query.h"
#include "Aql/Query.h"
#include "Aql/QueryResultV8.h"
#include "Basics/StringBuffer.h"
#include "Basics/VelocyPackHelper.h"
#include "Indexes/GeoIndex2.h"
#include "Indexes/HashIndex.h"
#include "Indexes/SkiplistIndex.h"
#include "Utils/OperationCursor.h"
#include "Utils/SingleCollectionTransaction.h"
#include "Utils/V8TransactionContext.h"
@ -36,16 +33,12 @@
#include "V8/v8-conv.h"
#include "V8/v8-utils.h"
#include "V8/v8-vpack.h"
#include "V8Server/v8-shape-conv.h"
#include "V8Server/v8-vocbase.h"
#include "V8Server/v8-vocindex.h"
#include "V8Server/v8-wrapshapedjson.h"
#include "V8Server/V8VPackWrapper.h"
#include "VocBase/document-collection.h"
#include "VocBase/edge-collection.h"
#include "VocBase/ExampleMatcher.h"
#include "VocBase/vocbase.h"
#include "VocBase/VocShaper.h"
#include <velocypack/Builder.h>
#include <velocypack/Iterator.h>

View File

@ -3205,28 +3205,6 @@ arangodb::Index* TRI_EnsureFulltextIndexDocumentCollection(
return idx;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief executes a select-by-example query
////////////////////////////////////////////////////////////////////////////////
std::vector<TRI_doc_mptr_t> TRI_SelectByExample(
TRI_transaction_collection_t* trxCollection,
ExampleMatcher const& matcher) {
TRI_document_collection_t* document = trxCollection->_collection->_collection;
// use filtered to hold copies of the master pointer
std::vector<TRI_doc_mptr_t> filtered;
auto work = [&matcher, &filtered](TRI_doc_mptr_t const* ptr) {
if (matcher.matches(0, ptr)) {
filtered.emplace_back(*ptr);
}
return true;
};
document->primaryIndex()->invokeOnAllElements(work);
return filtered;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief rotate the current journal of the collection
/// use this for testing only

View File

@ -682,41 +682,6 @@ arangodb::Index* TRI_EnsureFulltextIndexDocumentCollection(
arangodb::Transaction* trx, TRI_document_collection_t*, TRI_idx_iid_t,
std::string const&, int, bool&);
////////////////////////////////////////////////////////////////////////////////
/// @brief executes a select-by-example query
////////////////////////////////////////////////////////////////////////////////
std::vector<TRI_doc_mptr_t> TRI_SelectByExample(
struct TRI_transaction_collection_t*,
arangodb::ExampleMatcher const& matcher);
////////////////////////////////////////////////////////////////////////////////
/// @brief executes a select-by-example query
/// TODO remove
////////////////////////////////////////////////////////////////////////////////
struct ShapedJsonHash {
size_t operator()(TRI_shaped_json_t const& shap) const {
uint64_t hash = 0x12345678;
hash = fasthash64(&shap._sid, sizeof(shap._sid), hash);
return static_cast<size_t>(
fasthash64(shap._data.data, shap._data.length, hash));
}
};
struct ShapedJsonEq {
bool operator()(TRI_shaped_json_t const& left,
TRI_shaped_json_t const& right) const {
if (left._sid != right._sid) {
return false;
}
if (left._data.length != right._data.length) {
return false;
}
return (memcmp(left._data.data, right._data.data, left._data.length) == 0);
}
};
////////////////////////////////////////////////////////////////////////////////
/// @brief rotate the current journal of the collection
/// use this for testing only