mirror of https://gitee.com/bigwinds/arangodb
fix invalidation
This commit is contained in:
parent
e86ed5c685
commit
66eec2ac7e
|
@ -622,6 +622,7 @@ SHELL_SERVER_AQL = @top_srcdir@/js/server/tests/aql-arithmetic.js \
|
|||
@top_srcdir@/js/server/tests/aql-queries-optimiser-sort-noncluster.js \
|
||||
@top_srcdir@/js/server/tests/aql-queries-simple.js \
|
||||
@top_srcdir@/js/server/tests/aql-queries-variables.js \
|
||||
@top_srcdir@/js/server/tests/aql-query-cache.js \
|
||||
@top_srcdir@/js/server/tests/aql-range.js \
|
||||
@top_srcdir@/js/server/tests/aql-ranges.js \
|
||||
@top_srcdir@/js/server/tests/aql-refaccess-attribute.js \
|
||||
|
|
|
@ -55,8 +55,8 @@ namespace triagens {
|
|||
}
|
||||
|
||||
~Collections () {
|
||||
for (auto it = _collections.begin(); it != _collections.end(); ++it) {
|
||||
delete (*it).second;
|
||||
for (auto& it : _collections) {
|
||||
delete it.second;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,15 +83,10 @@ namespace triagens {
|
|||
THROW_ARANGO_EXCEPTION(TRI_ERROR_QUERY_TOO_MANY_COLLECTIONS);
|
||||
}
|
||||
|
||||
auto collection = new Collection(name, _vocbase, accessType);
|
||||
try {
|
||||
_collections.emplace(std::make_pair(name, collection));
|
||||
}
|
||||
catch (...) {
|
||||
delete collection;
|
||||
throw;
|
||||
}
|
||||
return collection;
|
||||
std::unique_ptr<Collection> collection(new Collection(name, _vocbase, accessType));
|
||||
_collections.emplace(name, collection.get());
|
||||
|
||||
return collection.release();
|
||||
}
|
||||
else {
|
||||
// note that the collection is used in both read & write ops
|
||||
|
@ -112,8 +107,8 @@ namespace triagens {
|
|||
std::vector<std::string> result;
|
||||
result.reserve(_collections.size());
|
||||
|
||||
for (auto it = _collections.begin(); it != _collections.end(); ++it) {
|
||||
result.emplace_back((*it).first);
|
||||
for (auto const& it : _collections) {
|
||||
result.emplace_back(it.first);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -648,6 +648,7 @@ QueryResult Query::execute (QueryRegistry* registry) {
|
|||
res.warnings = warningsToJson(TRI_UNKNOWN_MEM_ZONE);
|
||||
res.json = TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, cacheResult.get()->_queryResult);
|
||||
res.stats = nullptr;
|
||||
res.cached = true;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -695,7 +696,14 @@ QueryResult Query::execute (QueryRegistry* registry) {
|
|||
}
|
||||
|
||||
// finally store the generated result in the query cache
|
||||
QueryCache::instance()->store(_vocbase, queryStringHash, _queryString, _queryLength, TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, jsonResult.json()), std::vector<std::string>());
|
||||
QueryCache::instance()->store(
|
||||
_vocbase,
|
||||
queryStringHash,
|
||||
_queryString,
|
||||
_queryLength,
|
||||
TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, jsonResult.json()),
|
||||
collections()->collectionNames()
|
||||
);
|
||||
}
|
||||
else {
|
||||
// iterate over result and return it
|
||||
|
@ -782,6 +790,7 @@ QueryResultV8 Query::executeV8 (v8::Isolate* isolate,
|
|||
// got a result from the query cache
|
||||
QueryResultV8 res(TRI_ERROR_NO_ERROR);
|
||||
res.result = v8::Handle<v8::Array>::Cast(TRI_ObjectJson(isolate, cacheResult.get()->_queryResult));
|
||||
res.cached = true;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
@ -831,7 +840,14 @@ QueryResultV8 Query::executeV8 (v8::Isolate* isolate,
|
|||
}
|
||||
|
||||
// finally store the generated result in the query cache
|
||||
QueryCache::instance()->store(_vocbase, queryStringHash, _queryString, _queryLength, cacheResult.get(), std::vector<std::string>());
|
||||
QueryCache::instance()->store(
|
||||
_vocbase,
|
||||
queryStringHash,
|
||||
_queryString,
|
||||
_queryLength,
|
||||
cacheResult.get(),
|
||||
collections()->collectionNames()
|
||||
);
|
||||
cacheResult.release();
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -220,8 +220,7 @@ void QueryCacheDatabaseEntry::invalidate (char const* collection) {
|
|||
|
||||
QueryCache::QueryCache ()
|
||||
: _lock(),
|
||||
_entries(),
|
||||
_active(true) {
|
||||
_entries() {
|
||||
|
||||
}
|
||||
|
||||
|
@ -236,12 +235,25 @@ QueryCache::~QueryCache () {
|
|||
// --SECTION-- public methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return the query cache properties
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
triagens::basics::Json QueryCache::properties () const {
|
||||
triagens::basics::Json json(triagens::basics::Json::Object, 2);
|
||||
json("mode", triagens::basics::Json(modeString(mode())));
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test whether the cache might be active
|
||||
/// this is a quick test that may save the caller from further bothering
|
||||
/// about the query cache if case it returns `false`
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool QueryCache::mayBeActive () const {
|
||||
return (_active && (mode() != CACHE_ALWAYS_OFF));
|
||||
return (mode() != CACHE_ALWAYS_OFF);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -249,11 +261,6 @@ bool QueryCache::mayBeActive () const {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
QueryCacheMode QueryCache::mode () const {
|
||||
if (! _active) {
|
||||
// override whatever was stored in mode
|
||||
return CACHE_ALWAYS_OFF;
|
||||
}
|
||||
|
||||
return Mode.load(std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
|
@ -290,6 +297,24 @@ void QueryCache::mode (std::string const& value) {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return a string version of the mode
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string QueryCache::modeString (QueryCacheMode mode) {
|
||||
switch (mode) {
|
||||
case CACHE_ALWAYS_OFF:
|
||||
return "off";
|
||||
case CACHE_ALWAYS_ON:
|
||||
return "on";
|
||||
case CACHE_ON_DEMAND:
|
||||
return "demand";
|
||||
}
|
||||
|
||||
TRI_ASSERT(false);
|
||||
return "off";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief lookup a query result in the cache
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -323,6 +348,10 @@ void QueryCache::store (TRI_vocbase_t* vocbase,
|
|||
TRI_json_t* result,
|
||||
std::vector<std::string> const& collections) {
|
||||
|
||||
if (result == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<QueryCacheResultEntry> entry(new QueryCacheResultEntry(queryString, queryStringLength, result, collections));
|
||||
|
||||
WRITE_LOCKER(_lock);
|
||||
|
@ -348,7 +377,6 @@ void QueryCache::invalidate (triagens::basics::ReadWriteLock& lock,
|
|||
std::vector<char const*> const& collections) {
|
||||
TRI_ASSERT(&lock == &_lock); // this should be our lock
|
||||
|
||||
try {
|
||||
auto it = _entries.find(vocbase);
|
||||
|
||||
if (it == _entries.end()) {
|
||||
|
@ -357,11 +385,6 @@ void QueryCache::invalidate (triagens::basics::ReadWriteLock& lock,
|
|||
|
||||
// invalidate while holding the lock
|
||||
(*it).second->invalidate(collections);
|
||||
}
|
||||
catch (...) {
|
||||
// something is really wrong. now disable ourselves
|
||||
disable();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -370,7 +393,6 @@ void QueryCache::invalidate (triagens::basics::ReadWriteLock& lock,
|
|||
|
||||
void QueryCache::invalidate (TRI_vocbase_t* vocbase,
|
||||
std::vector<char const*> const& collections) {
|
||||
try {
|
||||
WRITE_LOCKER(_lock);
|
||||
|
||||
auto it = _entries.find(vocbase);
|
||||
|
@ -381,11 +403,6 @@ void QueryCache::invalidate (TRI_vocbase_t* vocbase,
|
|||
|
||||
// invalidate while holding the lock
|
||||
(*it).second->invalidate(collections);
|
||||
}
|
||||
catch (...) {
|
||||
// something is really wrong. now disable ourselves
|
||||
disable();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -394,7 +411,6 @@ void QueryCache::invalidate (TRI_vocbase_t* vocbase,
|
|||
|
||||
void QueryCache::invalidate (TRI_vocbase_t* vocbase,
|
||||
char const* collection) {
|
||||
try {
|
||||
WRITE_LOCKER(_lock);
|
||||
|
||||
auto it = _entries.find(vocbase);
|
||||
|
@ -405,11 +421,6 @@ void QueryCache::invalidate (TRI_vocbase_t* vocbase,
|
|||
|
||||
// invalidate while holding the lock
|
||||
(*it).second->invalidate(collection);
|
||||
}
|
||||
catch (...) {
|
||||
// something is really wrong. now disable ourselves
|
||||
disable();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -422,7 +433,6 @@ void QueryCache::invalidate (triagens::basics::ReadWriteLock& lock,
|
|||
char const* collection) {
|
||||
TRI_ASSERT(&lock == &_lock); // this should be our lock
|
||||
|
||||
try {
|
||||
auto it = _entries.find(vocbase);
|
||||
|
||||
if (it == _entries.end()) {
|
||||
|
@ -431,11 +441,6 @@ void QueryCache::invalidate (triagens::basics::ReadWriteLock& lock,
|
|||
|
||||
// invalidate while holding the lock
|
||||
(*it).second->invalidate(collection);
|
||||
}
|
||||
catch (...) {
|
||||
// something is really wrong. now disable ourselves
|
||||
disable();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -445,7 +450,6 @@ void QueryCache::invalidate (triagens::basics::ReadWriteLock& lock,
|
|||
void QueryCache::invalidate (TRI_vocbase_t* vocbase) {
|
||||
QueryCacheDatabaseEntry* databaseQueryCache = nullptr;
|
||||
|
||||
try {
|
||||
{
|
||||
WRITE_LOCKER(_lock);
|
||||
|
||||
|
@ -462,11 +466,6 @@ void QueryCache::invalidate (TRI_vocbase_t* vocbase) {
|
|||
// delete without holding the lock
|
||||
TRI_ASSERT(databaseQueryCache != nullptr);
|
||||
delete databaseQueryCache;
|
||||
}
|
||||
catch (...) {
|
||||
// something is really wrong. now disable ourselves
|
||||
disable();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -478,7 +477,6 @@ void QueryCache::invalidate (triagens::basics::ReadWriteLock& lock,
|
|||
TRI_vocbase_t* vocbase) {
|
||||
TRI_ASSERT(&lock == &_lock); // this should be our lock
|
||||
|
||||
try {
|
||||
QueryCacheDatabaseEntry* databaseQueryCache = nullptr;
|
||||
|
||||
auto it = _entries.find(vocbase);
|
||||
|
@ -493,20 +491,6 @@ void QueryCache::invalidate (triagens::basics::ReadWriteLock& lock,
|
|||
// delete without holding the lock
|
||||
TRI_ASSERT(databaseQueryCache != nullptr);
|
||||
delete databaseQueryCache;
|
||||
}
|
||||
catch (...) {
|
||||
// something is really wrong. now disable ourselves
|
||||
disable();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief disable ourselves in case of emergency
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void QueryCache::disable () {
|
||||
_active = false;
|
||||
mode(CACHE_ALWAYS_OFF);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#define ARANGODB_AQL_QUERY_CACHE_H 1
|
||||
|
||||
#include "Basics/Common.h"
|
||||
#include "Basics/JsonHelper.h"
|
||||
#include "Basics/ReadWriteLock.h"
|
||||
|
||||
struct TRI_json_t;
|
||||
|
@ -177,8 +178,16 @@ namespace triagens {
|
|||
|
||||
public:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return the query cache properties
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
triagens::basics::Json properties () const;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test whether the cache might be active
|
||||
/// this is a quick test that may save the caller from further bothering
|
||||
/// about the query cache if case it returns `false`
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool mayBeActive () const;
|
||||
|
@ -201,6 +210,12 @@ namespace triagens {
|
|||
|
||||
void mode (std::string const&);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return a string version of the mode
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static std::string modeString (QueryCacheMode);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief lookup a query result in the cache
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -277,12 +292,6 @@ namespace triagens {
|
|||
return _lock;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief disable ourselves in case of emergency
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void disable ();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get the pointer to the global query cache
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -318,13 +327,6 @@ namespace triagens {
|
|||
|
||||
std::unordered_map<struct TRI_vocbase_s*, QueryCacheDatabaseEntry*> _entries;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief activity flag. will be toggled to false only in case of something
|
||||
/// going terribly wrong
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool _active;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ namespace triagens {
|
|||
|
||||
QueryResult (QueryResult&& other) {
|
||||
code = other.code;
|
||||
cached = other.cached;
|
||||
details = other.details;
|
||||
warnings = other.warnings;
|
||||
json = other.json;
|
||||
|
@ -65,6 +66,7 @@ namespace triagens {
|
|||
QueryResult (int code,
|
||||
std::string const& details)
|
||||
: code(code),
|
||||
cached(false),
|
||||
details(details),
|
||||
zone(TRI_UNKNOWN_MEM_ZONE),
|
||||
warnings(nullptr),
|
||||
|
@ -98,6 +100,7 @@ namespace triagens {
|
|||
}
|
||||
|
||||
int code;
|
||||
bool cached;
|
||||
std::string details;
|
||||
std::unordered_set<std::string> bindParameters;
|
||||
std::vector<std::string> collectionNames;
|
||||
|
|
|
@ -1199,20 +1199,21 @@ static void JS_ExecuteAqlJson (const v8::FunctionCallbackInfo<v8::Value>& args)
|
|||
// return the array value as it is. this is a performance optimisation
|
||||
v8::Handle<v8::Object> result = v8::Object::New(isolate);
|
||||
if (queryResult.json != nullptr) {
|
||||
result->Set(TRI_V8_ASCII_STRING("json"), TRI_ObjectJson(isolate, queryResult.json));
|
||||
result->ForceSet(TRI_V8_ASCII_STRING("json"), TRI_ObjectJson(isolate, queryResult.json));
|
||||
}
|
||||
if (queryResult.stats != nullptr) {
|
||||
result->Set(TRI_V8_ASCII_STRING("stats"), TRI_ObjectJson(isolate, queryResult.stats));
|
||||
result->ForceSet(TRI_V8_ASCII_STRING("stats"), TRI_ObjectJson(isolate, queryResult.stats));
|
||||
}
|
||||
if (queryResult.profile != nullptr) {
|
||||
result->Set(TRI_V8_ASCII_STRING("profile"), TRI_ObjectJson(isolate, queryResult.profile));
|
||||
result->ForceSet(TRI_V8_ASCII_STRING("profile"), TRI_ObjectJson(isolate, queryResult.profile));
|
||||
}
|
||||
if (queryResult.warnings == nullptr) {
|
||||
result->Set(TRI_V8_ASCII_STRING("warnings"), v8::Array::New(isolate));
|
||||
result->ForceSet(TRI_V8_ASCII_STRING("warnings"), v8::Array::New(isolate));
|
||||
}
|
||||
else {
|
||||
result->Set(TRI_V8_ASCII_STRING("warnings"), TRI_ObjectJson(isolate, queryResult.warnings));
|
||||
result->ForceSet(TRI_V8_ASCII_STRING("warnings"), TRI_ObjectJson(isolate, queryResult.warnings));
|
||||
}
|
||||
result->ForceSet(TRI_V8_ASCII_STRING("cached"), v8::Boolean::New(isolate, queryResult.cached));
|
||||
|
||||
TRI_V8_RETURN(result);
|
||||
TRI_V8_TRY_CATCH_END
|
||||
|
@ -1299,20 +1300,21 @@ static void JS_ExecuteAql (const v8::FunctionCallbackInfo<v8::Value>& args) {
|
|||
// return the array value as it is. this is a performance optimisation
|
||||
v8::Handle<v8::Object> result = v8::Object::New(isolate);
|
||||
|
||||
result->Set(TRI_V8_ASCII_STRING("json"), queryResult.result);
|
||||
result->ForceSet(TRI_V8_ASCII_STRING("json"), queryResult.result);
|
||||
|
||||
if (queryResult.stats != nullptr) {
|
||||
result->Set(TRI_V8_ASCII_STRING("stats"), TRI_ObjectJson(isolate, queryResult.stats));
|
||||
result->ForceSet(TRI_V8_ASCII_STRING("stats"), TRI_ObjectJson(isolate, queryResult.stats));
|
||||
}
|
||||
if (queryResult.profile != nullptr) {
|
||||
result->Set(TRI_V8_ASCII_STRING("profile"), TRI_ObjectJson(isolate, queryResult.profile));
|
||||
result->ForceSet(TRI_V8_ASCII_STRING("profile"), TRI_ObjectJson(isolate, queryResult.profile));
|
||||
}
|
||||
if (queryResult.warnings == nullptr) {
|
||||
result->Set(TRI_V8_ASCII_STRING("warnings"), v8::Array::New(isolate));
|
||||
result->ForceSet(TRI_V8_ASCII_STRING("warnings"), v8::Array::New(isolate));
|
||||
}
|
||||
else {
|
||||
result->Set(TRI_V8_ASCII_STRING("warnings"), TRI_ObjectJson(isolate, queryResult.warnings));
|
||||
result->ForceSet(TRI_V8_ASCII_STRING("warnings"), TRI_ObjectJson(isolate, queryResult.warnings));
|
||||
}
|
||||
result->ForceSet(TRI_V8_ASCII_STRING("cached"), v8::Boolean::New(isolate, queryResult.cached));
|
||||
|
||||
TRI_V8_RETURN(result);
|
||||
TRI_V8_TRY_CATCH_END
|
||||
|
@ -1532,7 +1534,7 @@ static void JS_QueryIsKilledAql (const v8::FunctionCallbackInfo<v8::Value>& args
|
|||
/// @brief configures the AQL query cache
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void JS_QueryCacheConfigAql (const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
static void JS_QueryCachePropertiesAql (const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
TRI_V8_TRY_CATCH_BEGIN(isolate);
|
||||
v8::HandleScope scope(isolate);
|
||||
|
||||
|
@ -1542,17 +1544,26 @@ static void JS_QueryCacheConfigAql (const v8::FunctionCallbackInfo<v8::Value>& a
|
|||
TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
if (args.Length() != 1 || ! args[0]->IsObject()) {
|
||||
TRI_V8_THROW_EXCEPTION_USAGE("AQL_QUERY_CACHE_CONFIG(<options>)");
|
||||
if (args.Length() > 1 || (args.Length() == 1 && ! args[0]->IsObject())) {
|
||||
TRI_V8_THROW_EXCEPTION_USAGE("AQL_QUERY_CACHE_PROPERTIES(<options>)");
|
||||
}
|
||||
|
||||
if (args.Length() == 1) {
|
||||
// called with options
|
||||
auto obj = args[0]->ToObject();
|
||||
|
||||
if (obj->Has(TRI_V8_ASCII_STRING("mode"))) {
|
||||
auto mode = TRI_ObjectToString(obj->Get(TRI_V8_ASCII_STRING("mode")));
|
||||
|
||||
// set mode
|
||||
triagens::aql::QueryCache::instance()->mode(mode);
|
||||
}
|
||||
}
|
||||
|
||||
auto properties = triagens::aql::QueryCache::instance()->properties();
|
||||
TRI_V8_RETURN(TRI_ObjectJson(isolate, properties.json()));
|
||||
|
||||
// fetch current configuration and return it
|
||||
TRI_V8_TRY_CATCH_END
|
||||
}
|
||||
|
||||
|
@ -3753,7 +3764,7 @@ void TRI_InitV8VocBridge (v8::Isolate* isolate,
|
|||
TRI_AddGlobalFunctionVocbase(isolate, context, TRI_V8_ASCII_STRING("AQL_QUERIES_KILL"), JS_QueriesKillAql, true);
|
||||
TRI_AddGlobalFunctionVocbase(isolate, context, TRI_V8_ASCII_STRING("AQL_QUERY_SLEEP"), JS_QuerySleepAql, true);
|
||||
TRI_AddGlobalFunctionVocbase(isolate, context, TRI_V8_ASCII_STRING("AQL_QUERY_IS_KILLED"), JS_QueryIsKilledAql, true);
|
||||
TRI_AddGlobalFunctionVocbase(isolate, context, TRI_V8_ASCII_STRING("AQL_QUERY_CACHE_CONFIG"), JS_QueryCacheConfigAql, true);
|
||||
TRI_AddGlobalFunctionVocbase(isolate, context, TRI_V8_ASCII_STRING("AQL_QUERY_CACHE_PROPERTIES"), JS_QueryCachePropertiesAql, true);
|
||||
TRI_AddGlobalFunctionVocbase(isolate, context, TRI_V8_ASCII_STRING("AQL_QUERY_CACHE_INVALIDATE"), JS_QueryCacheInvalidateAql, true);
|
||||
|
||||
TRI_AddGlobalFunctionVocbase(isolate, context, TRI_V8_ASCII_STRING("CPP_SHORTEST_PATH"), JS_QueryShortestPath, true);
|
||||
|
|
|
@ -149,7 +149,7 @@ void ClearQueryCache (TRI_transaction_t* trx) {
|
|||
}
|
||||
catch (...) {
|
||||
// in case something goes wrong, we have to disable the query cache
|
||||
triagens::aql::QueryCache::instance()->disable();
|
||||
triagens::aql::QueryCache::instance()->invalidate(trx->_vocbase);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
/*jshint globalstrict:false, strict:false, maxlen: 500 */
|
||||
/*global assertEqual, assertTrue, assertFalse, AQL_EXECUTE,
|
||||
AQL_QUERY_CACHE_PROPERTIES, AQL_QUERY_CACHE_INVALIDATE */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief tests for query language, bind parameters
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var jsunity = require("jsunity");
|
||||
var db = require("org/arangodb").db;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test suite
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function ahuacatlQueryCacheTestSuite () {
|
||||
var cacheProperties;
|
||||
var c1, c2;
|
||||
|
||||
return {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief set up
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
setUp : function () {
|
||||
cacheProperties = AQL_QUERY_CACHE_PROPERTIES();
|
||||
AQL_QUERY_CACHE_INVALIDATE();
|
||||
|
||||
db._drop("UnitTestsAhuacatlQueryCache1");
|
||||
db._drop("UnitTestsAhuacatlQueryCache2");
|
||||
|
||||
c1 = db._create("UnitTestsAhuacatlQueryCache1");
|
||||
c2 = db._create("UnitTestsAhuacatlQueryCache2");
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief tear down
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
tearDown : function () {
|
||||
db._drop("UnitTestsAhuacatlQueryCache1");
|
||||
db._drop("UnitTestsAhuacatlQueryCache2");
|
||||
|
||||
c1 = null;
|
||||
c2 = null;
|
||||
|
||||
AQL_QUERY_CACHE_PROPERTIES(cacheProperties);
|
||||
AQL_QUERY_CACHE_INVALIDATE();
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test setting modes
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testModes : function () {
|
||||
var result;
|
||||
|
||||
result = AQL_QUERY_CACHE_PROPERTIES({ mode: "off" });
|
||||
assertEqual("off", result.mode);
|
||||
result = AQL_QUERY_CACHE_PROPERTIES();
|
||||
assertEqual("off", result.mode);
|
||||
|
||||
result = AQL_QUERY_CACHE_PROPERTIES({ mode: "on" });
|
||||
assertEqual("on", result.mode);
|
||||
result = AQL_QUERY_CACHE_PROPERTIES();
|
||||
assertEqual("on", result.mode);
|
||||
|
||||
result = AQL_QUERY_CACHE_PROPERTIES({ mode: "demand" });
|
||||
assertEqual("demand", result.mode);
|
||||
result = AQL_QUERY_CACHE_PROPERTIES();
|
||||
assertEqual("demand", result.mode);
|
||||
},
|
||||
|
||||
testInvalidationAfterInsertSingle : function () {
|
||||
var query = "FOR doc IN @@collection SORT doc.value RETURN doc.value";
|
||||
var result;
|
||||
|
||||
c1.save({ value: 1 });
|
||||
|
||||
AQL_QUERY_CACHE_PROPERTIES({ mode: "on" });
|
||||
result = AQL_EXECUTE(query, { "@collection": c1.name() });
|
||||
assertFalse(result.cached);
|
||||
assertEqual([ 1 ], result.json);
|
||||
|
||||
result = AQL_EXECUTE(query, { "@collection": c1.name() });
|
||||
assertTrue(result.cached);
|
||||
assertEqual([ 1 ], result.json);
|
||||
|
||||
c1.save({ value: 2 }); // this will invalidate cache
|
||||
|
||||
result = AQL_EXECUTE(query, { "@collection": c1.name() });
|
||||
assertFalse(result.cached);
|
||||
assertEqual([ 1, 2 ], result.json);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief executes the test suite
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
jsunity.run(ahuacatlQueryCacheTestSuite);
|
||||
|
||||
return jsunity.done();
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
|
||||
// End:
|
Loading…
Reference in New Issue