mirror of https://gitee.com/bigwinds/arangodb
use bulk allocator for index elements
This commit is contained in:
parent
fe8301cd31
commit
f0a4d69b69
|
@ -84,7 +84,7 @@ V8Expression* Executor::generateExpression(AstNode const* node) {
|
|||
v8::Handle<v8::Script> compiled = v8::Script::Compile(
|
||||
TRI_V8_STD_STRING((*_buffer)), TRI_V8_ASCII_STRING("--script--"));
|
||||
|
||||
if (! compiled.IsEmpty()) {
|
||||
if (!compiled.IsEmpty()) {
|
||||
v8::Handle<v8::Value> func(compiled->Run());
|
||||
|
||||
// exit early if an error occurred
|
||||
|
@ -108,7 +108,7 @@ V8Expression* Executor::generateExpression(AstNode const* node) {
|
|||
HandleV8Error(tryCatch, empty, _buffer, true);
|
||||
|
||||
// well we're almost sure we never reach this since the above call should throw:
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "unable to compile AQL script code");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,7 +133,7 @@ int Executor::executeExpression(Query* query, AstNode const* node,
|
|||
v8::Handle<v8::Script> compiled = v8::Script::Compile(
|
||||
TRI_V8_STD_STRING((*_buffer)), TRI_V8_ASCII_STRING("--script--"));
|
||||
|
||||
if (! compiled.IsEmpty()) {
|
||||
if (!compiled.IsEmpty()) {
|
||||
|
||||
v8::Handle<v8::Value> func(compiled->Run());
|
||||
|
||||
|
@ -175,7 +175,7 @@ int Executor::executeExpression(Query* query, AstNode const* node,
|
|||
HandleV8Error(tryCatch, empty, _buffer, true);
|
||||
|
||||
// well we're almost sure we never reach this since the above call should throw:
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "unable to compile AQL script code");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4010,7 +4010,7 @@ AqlValue Functions::Fulltext(arangodb::aql::Query* query,
|
|||
TRI_QueryFulltextIndex(fulltextIndex->internals(), ft);
|
||||
|
||||
if (queryResult == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
TRI_ASSERT(trx->hasDitch(cid));
|
||||
|
|
|
@ -499,7 +499,7 @@ void RestAqlHandler::getInfoQuery(std::string const& operation,
|
|||
auto block = static_cast<BlockWithClients*>(query->engine()->root());
|
||||
if (block->getPlanNode()->getType() != ExecutionNode::SCATTER &&
|
||||
block->getPlanNode()->getType() != ExecutionNode::DISTRIBUTE) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "unexpected node type");
|
||||
}
|
||||
number = block->remainingForShard(shardId);
|
||||
}
|
||||
|
@ -516,7 +516,7 @@ void RestAqlHandler::getInfoQuery(std::string const& operation,
|
|||
auto block = static_cast<BlockWithClients*>(query->engine()->root());
|
||||
if (block->getPlanNode()->getType() != ExecutionNode::SCATTER &&
|
||||
block->getPlanNode()->getType() != ExecutionNode::DISTRIBUTE) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "unexpected node type");
|
||||
}
|
||||
hasMore = block->hasMoreForShard(shardId);
|
||||
}
|
||||
|
@ -719,7 +719,7 @@ void RestAqlHandler::handleUseQuery(std::string const& operation, Query* query,
|
|||
auto block = static_cast<BlockWithClients*>(query->engine()->root());
|
||||
if (block->getPlanNode()->getType() != ExecutionNode::SCATTER &&
|
||||
block->getPlanNode()->getType() != ExecutionNode::DISTRIBUTE) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "unexpected node type");
|
||||
}
|
||||
items.reset(block->getSomeForShard(atLeast, atMost, shardId));
|
||||
}
|
||||
|
@ -755,7 +755,7 @@ void RestAqlHandler::handleUseQuery(std::string const& operation, Query* query,
|
|||
static_cast<BlockWithClients*>(query->engine()->root());
|
||||
if (block->getPlanNode()->getType() != ExecutionNode::SCATTER &&
|
||||
block->getPlanNode()->getType() != ExecutionNode::DISTRIBUTE) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "unexpected node type");
|
||||
}
|
||||
skipped = block->skipSomeForShard(atLeast, atMost, shardId);
|
||||
}
|
||||
|
@ -783,7 +783,7 @@ void RestAqlHandler::handleUseQuery(std::string const& operation, Query* query,
|
|||
static_cast<BlockWithClients*>(query->engine()->root());
|
||||
if (block->getPlanNode()->getType() != ExecutionNode::SCATTER &&
|
||||
block->getPlanNode()->getType() != ExecutionNode::DISTRIBUTE) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "unexpected node type");
|
||||
}
|
||||
exhausted = block->skipForShard(number, shardId);
|
||||
}
|
||||
|
|
|
@ -203,7 +203,7 @@ void Scopes::replaceVariable(Variable* variable) {
|
|||
}
|
||||
}
|
||||
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "unable to find AQL variable in scopes");
|
||||
}
|
||||
|
||||
/// @brief checks whether a variable exists in any scope
|
||||
|
|
|
@ -60,7 +60,7 @@ static AstNode* createGlobalCondition(Ast* ast, AstNode const* condition) {
|
|||
type = NODE_TYPE_OPERATOR_BINARY_NIN;
|
||||
break;
|
||||
default:
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "unsupported operator type");
|
||||
}
|
||||
auto quantifier = condition->getMemberUnchecked(2);
|
||||
TRI_ASSERT(quantifier->type == NODE_TYPE_QUANTIFIER);
|
||||
|
@ -69,7 +69,7 @@ static AstNode* createGlobalCondition(Ast* ast, AstNode const* condition) {
|
|||
if (val == Quantifier::NONE) {
|
||||
auto it = Ast::NegatedOperators.find(type);
|
||||
if (it == Ast::NegatedOperators.end()) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "unsupported operator type");
|
||||
}
|
||||
type = it->second;
|
||||
}
|
||||
|
|
|
@ -699,7 +699,7 @@ void ClusterComm::asyncAnswer(std::string& coordinatorHeader,
|
|||
// FIXME - generalize for VPP
|
||||
HttpResponse* responseToSend = dynamic_cast<HttpResponse*>(response);
|
||||
if (responseToSend == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid response type");
|
||||
}
|
||||
|
||||
// First take apart the header to get the coordinatorID:
|
||||
|
|
|
@ -1641,7 +1641,7 @@ static void Return_PrepareClusterCommResultForJS(
|
|||
// FIXME HANDLE VPP
|
||||
auto httpRequest = std::dynamic_pointer_cast<HttpRequest>(res.answer);
|
||||
if (httpRequest == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid request type");
|
||||
}
|
||||
|
||||
// The headers:
|
||||
|
|
|
@ -85,7 +85,7 @@ FulltextIndex::FulltextIndex(TRI_idx_iid_t iid,
|
|||
_sparse = true;
|
||||
if (_fields.size() != 1) {
|
||||
// We need exactly 1 attribute
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "fulltext index definition should have exactly one attribute");
|
||||
}
|
||||
auto& attribute = _fields[0];
|
||||
_attr.reserve(attribute.size());
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "Aql/AstNode.h"
|
||||
#include "Aql/SortCondition.h"
|
||||
#include "Basics/Exceptions.h"
|
||||
#include "Basics/FixedSizeAllocator.h"
|
||||
#include "Basics/VelocyPackHelper.h"
|
||||
#include "Indexes/IndexLookupContext.h"
|
||||
#include "Indexes/SimpleAttributeEqualityMatcher.h"
|
||||
|
@ -432,13 +433,6 @@ HashIndex::UniqueArray::UniqueArray(
|
|||
|
||||
/// @brief destroy the unique array
|
||||
HashIndex::UniqueArray::~UniqueArray() {
|
||||
if (_hashArray != nullptr) {
|
||||
auto cb = [this](HashIndexElement* element) -> bool {
|
||||
element->free(); return true;
|
||||
};
|
||||
_hashArray->invokeOnAllElements(cb);
|
||||
}
|
||||
|
||||
delete _hashArray;
|
||||
delete _hashElement;
|
||||
delete _isEqualElElByKey;
|
||||
|
@ -460,13 +454,6 @@ HashIndex::MultiArray::MultiArray(size_t numPaths,
|
|||
|
||||
/// @brief destroy the multi array
|
||||
HashIndex::MultiArray::~MultiArray() {
|
||||
if (_hashArray != nullptr) {
|
||||
auto cb = [this](HashIndexElement* element) -> bool {
|
||||
element->free(); return true;
|
||||
};
|
||||
_hashArray->invokeOnAllElements(cb);
|
||||
}
|
||||
|
||||
delete _hashArray;
|
||||
delete _hashElement;
|
||||
delete _isEqualElElByKey;
|
||||
|
@ -474,7 +461,7 @@ HashIndex::MultiArray::~MultiArray() {
|
|||
|
||||
HashIndex::HashIndex(TRI_idx_iid_t iid, LogicalCollection* collection,
|
||||
VPackSlice const& info)
|
||||
: PathBasedIndex(iid, collection, info, false), _uniqueArray(nullptr) {
|
||||
: PathBasedIndex(iid, collection, info, sizeof(TRI_voc_rid_t) + sizeof(uint32_t), false), _uniqueArray(nullptr) {
|
||||
uint32_t indexBuckets = 1;
|
||||
|
||||
if (collection != nullptr) {
|
||||
|
@ -650,7 +637,7 @@ int HashIndex::remove(arangodb::Transaction* trx, TRI_voc_rid_t revisionId,
|
|||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
for (auto& hashElement : elements) {
|
||||
hashElement->free();
|
||||
_allocator->deallocate(hashElement);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -668,7 +655,7 @@ int HashIndex::remove(arangodb::Transaction* trx, TRI_voc_rid_t revisionId,
|
|||
if (result != TRI_ERROR_NO_ERROR) {
|
||||
res = result;
|
||||
}
|
||||
hashElement->free();
|
||||
_allocator->deallocate(hashElement);
|
||||
}
|
||||
|
||||
return res;
|
||||
|
@ -686,10 +673,11 @@ int HashIndex::batchInsert(arangodb::Transaction* trx,
|
|||
|
||||
int HashIndex::unload() {
|
||||
if (_unique) {
|
||||
_uniqueArray->_hashArray->truncate([](HashIndexElement* element) -> bool { element->free(); return true; });
|
||||
_uniqueArray->_hashArray->truncate([](HashIndexElement*) -> bool { return true; });
|
||||
} else {
|
||||
_multiArray->_hashArray->truncate([](HashIndexElement* element) -> bool { element->free(); return true; });
|
||||
_multiArray->_hashArray->truncate([](HashIndexElement*) -> bool { return true; });
|
||||
}
|
||||
_allocator->deallocateAll();
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
|
@ -751,7 +739,7 @@ int HashIndex::insertUnique(arangodb::Transaction* trx, TRI_voc_rid_t revisionId
|
|||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
for (auto& it : elements) {
|
||||
// free all elements to prevent leak
|
||||
it->free();
|
||||
_allocator->deallocate(it);
|
||||
}
|
||||
|
||||
return res;
|
||||
|
@ -775,7 +763,7 @@ int HashIndex::insertUnique(arangodb::Transaction* trx, TRI_voc_rid_t revisionId
|
|||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
for (size_t j = i; j < n; ++j) {
|
||||
// Free all elements that are not yet in the index
|
||||
elements[j]->free();
|
||||
_allocator->deallocate(elements[j]);
|
||||
}
|
||||
// Already indexed elements will be removed by the rollback
|
||||
break;
|
||||
|
@ -796,7 +784,7 @@ int HashIndex::batchInsertUnique(arangodb::Transaction* trx,
|
|||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
for (auto& it : elements) {
|
||||
// free all elements to prevent leak
|
||||
it->free();
|
||||
_allocator->deallocate(it);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -823,7 +811,7 @@ int HashIndex::batchInsertUnique(arangodb::Transaction* trx,
|
|||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
for (auto& it : elements) {
|
||||
// free all elements to prevent leak
|
||||
it->free();
|
||||
_allocator->deallocate(it);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -837,7 +825,7 @@ int HashIndex::insertMulti(arangodb::Transaction* trx, TRI_voc_rid_t revisionId,
|
|||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
for (auto& hashElement : elements) {
|
||||
hashElement->free();
|
||||
_allocator->deallocate(hashElement);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -855,7 +843,7 @@ int HashIndex::insertMulti(arangodb::Transaction* trx, TRI_voc_rid_t revisionId,
|
|||
|
||||
if (found != nullptr) {
|
||||
// already got the exact same index entry. now free our local element...
|
||||
element->free();
|
||||
_allocator->deallocate(element);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -875,7 +863,7 @@ int HashIndex::insertMulti(arangodb::Transaction* trx, TRI_voc_rid_t revisionId,
|
|||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
for (size_t j = i; j < n; ++j) {
|
||||
// Free all elements that are not yet in the index
|
||||
elements[j]->free();
|
||||
_allocator->deallocate(elements[j]);
|
||||
}
|
||||
for (size_t j = 0; j < i; ++j) {
|
||||
// Remove all already indexed elements and free them
|
||||
|
@ -903,7 +891,7 @@ int HashIndex::batchInsertMulti(arangodb::Transaction* trx,
|
|||
// Filling the elements failed for some reason. Assume loading as failed
|
||||
for (auto& el : elements) {
|
||||
// Free all elements that are not yet in the index
|
||||
el->free();
|
||||
_allocator->deallocate(el);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -943,7 +931,7 @@ int HashIndex::removeUniqueElement(arangodb::Transaction* trx,
|
|||
}
|
||||
return TRI_ERROR_INTERNAL;
|
||||
}
|
||||
old->free();
|
||||
_allocator->deallocate(old);
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
@ -963,7 +951,7 @@ int HashIndex::removeMultiElement(arangodb::Transaction* trx,
|
|||
}
|
||||
return TRI_ERROR_INTERNAL;
|
||||
}
|
||||
old->free();
|
||||
_allocator->deallocate(old);
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
|
|
@ -35,26 +35,13 @@ HashIndexElement::HashIndexElement(TRI_voc_rid_t revisionId, std::vector<std::pa
|
|||
}
|
||||
}
|
||||
|
||||
HashIndexElement* HashIndexElement::create(TRI_voc_rid_t revisionId, std::vector<std::pair<arangodb::velocypack::Slice, uint32_t>> const& values) {
|
||||
HashIndexElement* HashIndexElement::initialize(HashIndexElement* element,
|
||||
TRI_voc_rid_t revisionId,
|
||||
std::vector<std::pair<arangodb::velocypack::Slice, uint32_t>> const& values) {
|
||||
TRI_ASSERT(!values.empty());
|
||||
void* space = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, baseMemoryUsage(values.size()), false);
|
||||
|
||||
if (space == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
try {
|
||||
return new (space) HashIndexElement(revisionId, values);
|
||||
} catch (...) {
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, space);
|
||||
return nullptr;
|
||||
}
|
||||
return new (element) HashIndexElement(revisionId, values);
|
||||
}
|
||||
|
||||
void HashIndexElement::free() {
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, this);
|
||||
}
|
||||
|
||||
/// @brief velocypack sub-object (for indexes, as part of IndexElement,
|
||||
/// if offset is non-zero, then it is an offset into the VelocyPack data in
|
||||
/// the datafile or WAL file. If offset is 0, then data contains the actual data
|
||||
|
@ -126,26 +113,13 @@ SkiplistIndexElement::SkiplistIndexElement(TRI_voc_rid_t revisionId, std::vector
|
|||
}
|
||||
}
|
||||
|
||||
SkiplistIndexElement* SkiplistIndexElement::create(TRI_voc_rid_t revisionId, std::vector<std::pair<arangodb::velocypack::Slice, uint32_t>> const& values) {
|
||||
SkiplistIndexElement* SkiplistIndexElement::initialize(SkiplistIndexElement* element,
|
||||
TRI_voc_rid_t revisionId,
|
||||
std::vector<std::pair<arangodb::velocypack::Slice, uint32_t>> const& values) {
|
||||
TRI_ASSERT(!values.empty());
|
||||
void* space = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, baseMemoryUsage(values.size()), false);
|
||||
|
||||
if (space == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
try {
|
||||
return new (space) SkiplistIndexElement(revisionId, values);
|
||||
} catch (...) {
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, space);
|
||||
return nullptr;
|
||||
}
|
||||
return new (element) SkiplistIndexElement(revisionId, values);
|
||||
}
|
||||
|
||||
void SkiplistIndexElement::free() {
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, this);
|
||||
}
|
||||
|
||||
/// @brief velocypack sub-object (for indexes, as part of IndexElement,
|
||||
/// if offset is non-zero, then it is an offset into the VelocyPack data in
|
||||
/// the datafile or WAL file. If offset is 0, then data contains the actual data
|
||||
|
|
|
@ -140,9 +140,9 @@ struct HashIndexElement {
|
|||
static uint64_t hash(std::vector<std::pair<arangodb::velocypack::Slice, uint32_t>> const& values);
|
||||
|
||||
/// @brief allocate a new index element from a vector of slices
|
||||
static HashIndexElement* create(TRI_voc_rid_t revisionId, std::vector<std::pair<arangodb::velocypack::Slice, uint32_t>> const& values);
|
||||
|
||||
void free();
|
||||
static HashIndexElement* initialize(HashIndexElement* memory,
|
||||
TRI_voc_rid_t revisionId,
|
||||
std::vector<std::pair<arangodb::velocypack::Slice, uint32_t>> const& values);
|
||||
|
||||
private:
|
||||
inline IndexElementValue* subObject(size_t position) {
|
||||
|
@ -188,9 +188,9 @@ struct SkiplistIndexElement {
|
|||
arangodb::velocypack::Slice slice(IndexLookupContext* context, size_t position) const;
|
||||
|
||||
/// @brief allocate a new index element from a vector of slices
|
||||
static SkiplistIndexElement* create(TRI_voc_rid_t revisionId, std::vector<std::pair<arangodb::velocypack::Slice, uint32_t>> const& values);
|
||||
|
||||
void free();
|
||||
static SkiplistIndexElement* initialize(SkiplistIndexElement* element,
|
||||
TRI_voc_rid_t revisionId,
|
||||
std::vector<std::pair<arangodb::velocypack::Slice, uint32_t>> const& values);
|
||||
|
||||
private:
|
||||
inline IndexElementValue* subObject(size_t position) {
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "PathBasedIndex.h"
|
||||
#include "Aql/AstNode.h"
|
||||
#include "Basics/FixedSizeAllocator.h"
|
||||
#include "Basics/VelocyPackHelper.h"
|
||||
#include "Logger/Logger.h"
|
||||
|
||||
|
@ -53,7 +54,7 @@ arangodb::aql::AstNode const* PathBasedIndex::PermutationState::getValue()
|
|||
/// @brief create the index
|
||||
PathBasedIndex::PathBasedIndex(TRI_idx_iid_t iid,
|
||||
arangodb::LogicalCollection* collection,
|
||||
VPackSlice const& info, bool allowPartialIndex)
|
||||
VPackSlice const& info, size_t baseSize, bool allowPartialIndex)
|
||||
: Index(iid, collection, info),
|
||||
_useExpansion(false),
|
||||
_allowPartialIndex(allowPartialIndex) {
|
||||
|
@ -69,10 +70,14 @@ PathBasedIndex::PathBasedIndex(TRI_idx_iid_t iid,
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_allocator.reset(new FixedSizeAllocator(baseSize + sizeof(IndexElementValue) * numPaths()));
|
||||
}
|
||||
|
||||
/// @brief destroy the index
|
||||
PathBasedIndex::~PathBasedIndex() {}
|
||||
PathBasedIndex::~PathBasedIndex() {
|
||||
_allocator->deallocateAll();
|
||||
}
|
||||
|
||||
/// @brief whether or not the index is implicitly unique
|
||||
/// this can be the case if the index is not declared as unique, but contains a
|
||||
|
@ -121,14 +126,16 @@ int PathBasedIndex::fillElement(std::vector<T*>& elements,
|
|||
if (slices.size() == n) {
|
||||
// if shapes.size() != n, then the value is not inserted into the index
|
||||
// because of index sparsity!
|
||||
T* element = T::create(revisionId, slices);
|
||||
T* element = static_cast<T*>(_allocator->allocate());
|
||||
TRI_ASSERT(element != nullptr);
|
||||
element = T::initialize(element, revisionId, slices);
|
||||
|
||||
if (element == nullptr) {
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
TRI_IF_FAILURE("FillElementOOM") {
|
||||
// clean up manually
|
||||
element->free();
|
||||
_allocator->deallocate(element);
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
@ -139,7 +146,7 @@ int PathBasedIndex::fillElement(std::vector<T*>& elements,
|
|||
|
||||
elements.emplace_back(element);
|
||||
} catch (...) {
|
||||
element->free();
|
||||
_allocator->deallocate(element);
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
@ -155,14 +162,16 @@ int PathBasedIndex::fillElement(std::vector<T*>& elements,
|
|||
|
||||
for (auto& info : toInsert) {
|
||||
TRI_ASSERT(info.size() == n);
|
||||
T* element = T::create(revisionId, info);
|
||||
T* element = static_cast<T*>(_allocator->allocate());
|
||||
TRI_ASSERT(element != nullptr);
|
||||
element = T::initialize(element, revisionId, info);
|
||||
|
||||
if (element == nullptr) {
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
TRI_IF_FAILURE("FillElementOOM") {
|
||||
// clean up manually
|
||||
element->free();
|
||||
_allocator->deallocate(element);
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
@ -173,7 +182,7 @@ int PathBasedIndex::fillElement(std::vector<T*>& elements,
|
|||
|
||||
elements.emplace_back(element);
|
||||
} catch (...) {
|
||||
element->free();
|
||||
_allocator->deallocate(element);
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,8 @@ namespace aql {
|
|||
enum AstNodeType : uint32_t;
|
||||
}
|
||||
|
||||
class FixedSizeAllocator;
|
||||
|
||||
class PathBasedIndex : public Index {
|
||||
protected:
|
||||
struct PermutationState {
|
||||
|
@ -61,7 +63,7 @@ class PathBasedIndex : public Index {
|
|||
PathBasedIndex() = delete;
|
||||
|
||||
PathBasedIndex(TRI_idx_iid_t, arangodb::LogicalCollection*,
|
||||
arangodb::velocypack::Slice const&, bool allowPartialIndex);
|
||||
arangodb::velocypack::Slice const&, size_t baseSize, bool allowPartialIndex);
|
||||
|
||||
~PathBasedIndex();
|
||||
|
||||
|
@ -105,6 +107,8 @@ class PathBasedIndex : public Index {
|
|||
std::vector<std::pair<VPackSlice, uint32_t>>& sliceStack);
|
||||
|
||||
protected:
|
||||
std::unique_ptr<FixedSizeAllocator> _allocator;
|
||||
|
||||
/// @brief the attribute paths
|
||||
std::vector<std::vector<std::string>> _paths;
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "Aql/AstNode.h"
|
||||
#include "Aql/SortCondition.h"
|
||||
#include "Basics/AttributeNameParser.h"
|
||||
#include "Basics/FixedSizeAllocator.h"
|
||||
#include "Basics/StaticStrings.h"
|
||||
#include "Basics/VelocyPackHelper.h"
|
||||
#include "Indexes/IndexLookupContext.h"
|
||||
|
@ -206,7 +207,7 @@ IndexLookupResult RocksDBIterator::next() {
|
|||
RocksDBIndex::RocksDBIndex(TRI_idx_iid_t iid,
|
||||
arangodb::LogicalCollection* collection,
|
||||
arangodb::velocypack::Slice const& info)
|
||||
: PathBasedIndex(iid, collection, info, true),
|
||||
: PathBasedIndex(iid, collection, info, 0, true),
|
||||
_db(RocksDBFeature::instance()->db()) {}
|
||||
|
||||
/// @brief destroy the index
|
||||
|
@ -246,7 +247,7 @@ int RocksDBIndex::insert(arangodb::Transaction* trx, TRI_voc_rid_t revisionId,
|
|||
// make sure we clean up before we leave this method
|
||||
auto cleanup = [this, &elements] {
|
||||
for (auto& it : elements) {
|
||||
it->free();
|
||||
_allocator->deallocate(it);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -402,7 +403,7 @@ int RocksDBIndex::remove(arangodb::Transaction* trx, TRI_voc_rid_t revisionId,
|
|||
// make sure we clean up before we leave this method
|
||||
auto cleanup = [this, &elements] {
|
||||
for (auto& it : elements) {
|
||||
it->free();
|
||||
_allocator->deallocate(it);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "Aql/AstNode.h"
|
||||
#include "Aql/SortCondition.h"
|
||||
#include "Basics/AttributeNameParser.h"
|
||||
#include "Basics/FixedSizeAllocator.h"
|
||||
#include "Basics/StaticStrings.h"
|
||||
#include "Basics/VelocyPackHelper.h"
|
||||
#include "Indexes/IndexLookupContext.h"
|
||||
|
@ -715,12 +716,12 @@ void SkiplistIterator2::initNextInterval() {
|
|||
SkiplistIndex::SkiplistIndex(TRI_idx_iid_t iid,
|
||||
arangodb::LogicalCollection* collection,
|
||||
VPackSlice const& info)
|
||||
: PathBasedIndex(iid, collection, info, true),
|
||||
: PathBasedIndex(iid, collection, info, sizeof(TRI_voc_rid_t), true),
|
||||
CmpElmElm(this),
|
||||
CmpKeyElm(this),
|
||||
_skiplistIndex(nullptr) {
|
||||
_skiplistIndex =
|
||||
new TRI_Skiplist(CmpElmElm, CmpKeyElm, [this](SkiplistIndexElement* element) { element->free(); }, _unique, _useExpansion);
|
||||
new TRI_Skiplist(CmpElmElm, CmpKeyElm, [this](SkiplistIndexElement* element) { _allocator->deallocate(element); }, _unique, _useExpansion);
|
||||
}
|
||||
|
||||
/// @brief destroy the skiplist index
|
||||
|
@ -761,7 +762,7 @@ int SkiplistIndex::insert(arangodb::Transaction* trx, TRI_voc_rid_t revisionId,
|
|||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
for (auto& element : elements) {
|
||||
// free all elements to prevent leak
|
||||
element->free();
|
||||
_allocator->deallocate(element);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -779,7 +780,7 @@ int SkiplistIndex::insert(arangodb::Transaction* trx, TRI_voc_rid_t revisionId,
|
|||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
// Note: this element is freed already
|
||||
for (size_t j = i; j < count; ++j) {
|
||||
elements[j]->free();
|
||||
_allocator->deallocate(elements[j]);
|
||||
}
|
||||
for (size_t j = 0; j < i; ++j) {
|
||||
_skiplistIndex->remove(&context, elements[j]);
|
||||
|
@ -812,7 +813,7 @@ int SkiplistIndex::remove(arangodb::Transaction* trx, TRI_voc_rid_t revisionId,
|
|||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
for (auto& element : elements) {
|
||||
// free all elements to prevent leak
|
||||
element->free();
|
||||
_allocator->deallocate(element);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -833,7 +834,7 @@ int SkiplistIndex::remove(arangodb::Transaction* trx, TRI_voc_rid_t revisionId,
|
|||
res = result;
|
||||
}
|
||||
|
||||
elements[i]->free();
|
||||
_allocator->deallocate(elements[i]);
|
||||
}
|
||||
|
||||
return res;
|
||||
|
|
|
@ -72,7 +72,7 @@ RestStatus RestBatchHandler::executeHttp() {
|
|||
|
||||
if (httpResponse == nullptr) {
|
||||
std::cout << "please fix this for vpack" << std::endl;
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid response type");
|
||||
}
|
||||
|
||||
HttpRequest const* httpRequest =
|
||||
|
@ -80,7 +80,7 @@ RestStatus RestBatchHandler::executeHttp() {
|
|||
|
||||
if (httpRequest == nullptr) {
|
||||
std::cout << "please fix this for vpack" << std::endl;
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid request type");
|
||||
}
|
||||
|
||||
// extract the request type
|
||||
|
@ -290,7 +290,7 @@ bool RestBatchHandler::getBoundaryBody(std::string* result) {
|
|||
HttpRequest const* req = dynamic_cast<HttpRequest const*>(_request.get());
|
||||
|
||||
if (req == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid request type");
|
||||
}
|
||||
|
||||
std::string const& bodyStr = req->body();
|
||||
|
|
|
@ -276,7 +276,7 @@ int RestImportHandler::handleSingleDocument(SingleCollectionTransaction& trx,
|
|||
|
||||
bool RestImportHandler::createFromJson(std::string const& type) {
|
||||
if (_request == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid request");
|
||||
}
|
||||
|
||||
RestImportResult result;
|
||||
|
@ -319,7 +319,7 @@ bool RestImportHandler::createFromJson(std::string const& type) {
|
|||
linewise = true;
|
||||
|
||||
if (_response == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid response");
|
||||
}
|
||||
|
||||
// auto detect import type by peeking at first non-whitespace character
|
||||
|
@ -328,7 +328,7 @@ bool RestImportHandler::createFromJson(std::string const& type) {
|
|||
HttpRequest* req = dynamic_cast<HttpRequest*>(_request.get());
|
||||
|
||||
if (req == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid request type");
|
||||
}
|
||||
|
||||
std::string const& body = req->body();
|
||||
|
@ -388,7 +388,7 @@ bool RestImportHandler::createFromJson(std::string const& type) {
|
|||
HttpRequest* req = dynamic_cast<HttpRequest*>(_request.get());
|
||||
|
||||
if (req == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid request type");
|
||||
}
|
||||
|
||||
// each line is a separate JSON document
|
||||
|
@ -529,7 +529,7 @@ bool RestImportHandler::createFromJson(std::string const& type) {
|
|||
|
||||
bool RestImportHandler::createFromVPack(std::string const& type) {
|
||||
if (_request == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid request");
|
||||
}
|
||||
|
||||
RestImportResult result;
|
||||
|
@ -637,7 +637,7 @@ bool RestImportHandler::createFromVPack(std::string const& type) {
|
|||
|
||||
bool RestImportHandler::createFromKeyValueList() {
|
||||
if (_request == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid request");
|
||||
}
|
||||
|
||||
RestImportResult result;
|
||||
|
@ -679,7 +679,7 @@ bool RestImportHandler::createFromKeyValueList() {
|
|||
HttpRequest* httpRequest = dynamic_cast<HttpRequest*>(_request.get());
|
||||
|
||||
if (httpRequest == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid request type");
|
||||
}
|
||||
|
||||
std::string const& bodyStr = httpRequest->body();
|
||||
|
|
|
@ -40,7 +40,7 @@ RestStatus RestPleaseUpgradeHandler::execute() {
|
|||
auto response = dynamic_cast<HttpResponse*>(_response.get());
|
||||
|
||||
if (response == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid response type");
|
||||
}
|
||||
|
||||
resetResponse(rest::ResponseCode::OK);
|
||||
|
|
|
@ -744,7 +744,7 @@ void RestReplicationHandler::handleTrampolineCoordinator() {
|
|||
useVpp = true;
|
||||
}
|
||||
if (_request == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid request");
|
||||
}
|
||||
|
||||
// First check the DBserver component of the body json:
|
||||
|
@ -783,7 +783,7 @@ void RestReplicationHandler::handleTrampolineCoordinator() {
|
|||
if (!useVpp) {
|
||||
HttpRequest* httpRequest = dynamic_cast<HttpRequest*>(_request.get());
|
||||
if (httpRequest == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid request type");
|
||||
}
|
||||
|
||||
// Send a synchronous request to that shard using ClusterComm:
|
||||
|
@ -833,7 +833,7 @@ void RestReplicationHandler::handleTrampolineCoordinator() {
|
|||
if (!useVpp) {
|
||||
HttpResponse* httpResponse = dynamic_cast<HttpResponse*>(_response.get());
|
||||
if (_response == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid response type");
|
||||
}
|
||||
httpResponse->body().swap(&(res->result->getBody()));
|
||||
} else {
|
||||
|
@ -1014,7 +1014,7 @@ void RestReplicationHandler::handleCommandLoggerFollow() {
|
|||
dynamic_cast<HttpResponse*>(_response.get());
|
||||
|
||||
if (httpResponse == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid response type");
|
||||
}
|
||||
|
||||
if (length > 0) {
|
||||
|
@ -1086,7 +1086,7 @@ void RestReplicationHandler::handleCommandDetermineOpenTransactions() {
|
|||
|
||||
HttpResponse* httpResponse = dynamic_cast<HttpResponse*>(_response.get());
|
||||
if (_response == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid response type");
|
||||
}
|
||||
|
||||
_response->setContentType(rest::ContentType::DUMP);
|
||||
|
@ -2132,7 +2132,7 @@ int RestReplicationHandler::processRestoreDataBatch(
|
|||
|
||||
HttpRequest* httpRequest = dynamic_cast<HttpRequest*>(_request.get());
|
||||
if (httpRequest == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid request type");
|
||||
}
|
||||
|
||||
std::string const& bodyStr = httpRequest->body();
|
||||
|
@ -2466,12 +2466,12 @@ void RestReplicationHandler::handleCommandRestoreDataCoordinator() {
|
|||
VPackBuilder builder;
|
||||
|
||||
if (_request == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid request type");
|
||||
}
|
||||
|
||||
HttpRequest* httpRequest = dynamic_cast<HttpRequest*>(_request.get());
|
||||
if (httpRequest == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid request type");
|
||||
}
|
||||
|
||||
std::string const& bodyStr = httpRequest->body();
|
||||
|
@ -3099,7 +3099,7 @@ void RestReplicationHandler::handleCommandDump() {
|
|||
auto response = dynamic_cast<HttpResponse*>(_response.get());
|
||||
|
||||
if (response == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid response type");
|
||||
}
|
||||
|
||||
response->setContentType(rest::ContentType::DUMP);
|
||||
|
|
|
@ -287,7 +287,7 @@ void RestSimpleHandler::lookupByKeys(VPackSlice const& slice) {
|
|||
auto response = _response.get();
|
||||
|
||||
if (response == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid response");
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
|
@ -46,7 +46,7 @@ RestStatus RestUploadHandler::execute() {
|
|||
HttpRequest* request = dynamic_cast<HttpRequest*>(_request.get());
|
||||
|
||||
if (request == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid request type");
|
||||
}
|
||||
|
||||
// extract the request type
|
||||
|
@ -152,7 +152,7 @@ bool RestUploadHandler::parseMultiPart(char const*& body, size_t& length) {
|
|||
HttpRequest* request = dynamic_cast<HttpRequest*>(_request.get());
|
||||
|
||||
if (request == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid request type");
|
||||
}
|
||||
|
||||
std::string const& bodyStr = request->body();
|
||||
|
|
|
@ -159,7 +159,7 @@ void VelocyPackCursor::dump(VPackBuilder& builder) {
|
|||
} catch (std::exception const& ex) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, ex.what());
|
||||
} catch (...) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "internal error during VPackCursor::dump");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -298,7 +298,7 @@ void ExportCursor::dump(VPackBuilder& builder) {
|
|||
} catch (std::exception const& ex) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, ex.what());
|
||||
} catch (...) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "internal error during ExportCursor::dump");
|
||||
}
|
||||
builder.options = oldOptions;
|
||||
}
|
||||
|
|
|
@ -649,7 +649,7 @@ DocumentDitch* Transaction::orderDitch(TRI_voc_cid_t cid) {
|
|||
TRI_transaction_collection_t* trxCollection = TRI_GetCollectionTransaction(_trx, cid, TRI_TRANSACTION_READ);
|
||||
|
||||
if (trxCollection == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "unable to determine transaction collection");
|
||||
}
|
||||
|
||||
TRI_ASSERT(trxCollection->_collection != nullptr);
|
||||
|
|
|
@ -407,7 +407,7 @@ static v8::Handle<v8::Object> RequestCppToV8(v8::Isolate* isolate,
|
|||
if (rest::ContentType::JSON == request->contentType()) {
|
||||
auto httpreq = dynamic_cast<HttpRequest*>(request);
|
||||
if (httpreq == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid request type");
|
||||
}
|
||||
std::string const& body = httpreq->body();
|
||||
req->ForceSet(RequestBodyKey, TRI_V8_STD_STRING(body));
|
||||
|
@ -516,7 +516,7 @@ static v8::Handle<v8::Object> RequestCppToV8(v8::Isolate* isolate,
|
|||
HttpRequest* httpRequest = dynamic_cast<HttpRequest*>(request);
|
||||
if (httpRequest == nullptr) {
|
||||
// maybe we can just continue
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid request type");
|
||||
} else {
|
||||
for (auto& it : httpRequest->cookieValues()) {
|
||||
cookiesObject->ForceSet(TRI_V8_STD_STRING(it.first),
|
||||
|
@ -832,7 +832,7 @@ static TRI_action_result_t ExecuteActionVocbase(
|
|||
v8::TryCatch tryCatch;
|
||||
|
||||
if (response == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid response");
|
||||
}
|
||||
|
||||
TRI_GET_GLOBALS();
|
||||
|
|
|
@ -111,7 +111,7 @@ static void EdgesQuery(TRI_edge_direction_e direction,
|
|||
return "FILTER doc._from " + op + " @value || doc._to " + op + " @value";
|
||||
}
|
||||
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid edge index direction");
|
||||
};
|
||||
|
||||
arangodb::LogicalCollection const* collection =
|
||||
|
|
|
@ -433,7 +433,7 @@ static void JS_ConfigureApplierReplication(
|
|||
}
|
||||
|
||||
if (vocbase->replicationApplier() == nullptr) {
|
||||
TRI_V8_THROW_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "unable to find replicationApplier");
|
||||
}
|
||||
|
||||
if (args.Length() == 0) {
|
||||
|
@ -702,7 +702,7 @@ static void JS_StartApplierReplication(
|
|||
}
|
||||
|
||||
if (vocbase->replicationApplier() == nullptr) {
|
||||
TRI_V8_THROW_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "unable to find replicationApplier");
|
||||
}
|
||||
|
||||
if (args.Length() > 2) {
|
||||
|
@ -753,7 +753,7 @@ static void JS_ShutdownApplierReplication(
|
|||
}
|
||||
|
||||
if (vocbase->replicationApplier() == nullptr) {
|
||||
TRI_V8_THROW_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "unable to find replicationApplier");
|
||||
}
|
||||
|
||||
int res = vocbase->replicationApplier()->shutdown();
|
||||
|
@ -786,7 +786,7 @@ static void JS_StateApplierReplication(
|
|||
}
|
||||
|
||||
if (vocbase->replicationApplier() == nullptr) {
|
||||
TRI_V8_THROW_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "unable to find replicationApplier");
|
||||
}
|
||||
|
||||
std::shared_ptr<VPackBuilder> builder = vocbase->replicationApplier()->toVelocyPack();
|
||||
|
@ -817,7 +817,7 @@ static void JS_ForgetApplierReplication(
|
|||
}
|
||||
|
||||
if (vocbase->replicationApplier() == nullptr) {
|
||||
TRI_V8_THROW_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "unable to find replicationApplier");
|
||||
}
|
||||
|
||||
int res = vocbase->replicationApplier()->forget();
|
||||
|
|
|
@ -286,7 +286,7 @@ static void JS_Transaction(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|||
}
|
||||
|
||||
if (params.IsEmpty()) {
|
||||
TRI_V8_THROW_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "unable to decode function parameters");
|
||||
}
|
||||
|
||||
bool embed = false;
|
||||
|
@ -375,7 +375,7 @@ static void JS_Transaction(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|||
} catch (std::exception const& ex) {
|
||||
TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, ex.what());
|
||||
} catch (...) {
|
||||
TRI_V8_THROW_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "caught unknown exception during transaction");
|
||||
}
|
||||
|
||||
res = trx.commit();
|
||||
|
@ -2044,7 +2044,7 @@ static void JS_UseDatabase(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|||
TRI_vocbase_t* vocbase = GetContextVocBase(isolate);
|
||||
|
||||
if (vocbase == nullptr) {
|
||||
TRI_V8_THROW_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "unable to find database");
|
||||
}
|
||||
|
||||
if (vocbase->isDropped()) {
|
||||
|
@ -2270,7 +2270,7 @@ static void CreateDatabaseCoordinator(
|
|||
}
|
||||
|
||||
if (vocbase == nullptr) {
|
||||
TRI_V8_THROW_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "unable to find database");
|
||||
}
|
||||
|
||||
// now run upgrade and copy users into context
|
||||
|
|
|
@ -599,7 +599,7 @@ static void EnsureIndex(v8::FunctionCallbackInfo<v8::Value> const& args,
|
|||
VPackSlice f = flds.at(i);
|
||||
if (!f.isString()) {
|
||||
// index attributes must be strings
|
||||
TRI_V8_THROW_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "index field names should be strings");
|
||||
}
|
||||
indexKeys.emplace(f.copyString());
|
||||
}
|
||||
|
|
|
@ -244,7 +244,7 @@ static std::shared_ptr<Index> PrepareIndexFromSlice(VPackSlice info,
|
|||
|
||||
switch (type) {
|
||||
case arangodb::Index::TRI_IDX_TYPE_UNKNOWN: {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid index type");
|
||||
}
|
||||
case arangodb::Index::TRI_IDX_TYPE_PRIMARY_INDEX: {
|
||||
if (!isClusterConstructor) {
|
||||
|
|
|
@ -52,7 +52,7 @@ template <typename T>
|
|||
static inline T NumericValue(VPackSlice const& slice, char const* attribute) {
|
||||
if (!slice.isObject()) {
|
||||
LOG(ERR) << "invalid value type when looking for attribute '" << attribute << "': expecting object";
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER, "invalid attribute value: expecting object");
|
||||
}
|
||||
VPackSlice v = slice.get(attribute);
|
||||
if (v.isString()) {
|
||||
|
@ -63,7 +63,7 @@ static inline T NumericValue(VPackSlice const& slice, char const* attribute) {
|
|||
}
|
||||
|
||||
LOG(ERR) << "invalid value for attribute '" << attribute << "'";
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER, "invalid attribute value");
|
||||
}
|
||||
|
||||
/// @brief creates the recover state
|
||||
|
|
|
@ -108,6 +108,8 @@ char const* Exception::what() const throw() { return _errorMessage.c_str(); }
|
|||
void Exception::appendLocation () {
|
||||
if (_code == TRI_ERROR_INTERNAL) {
|
||||
_errorMessage += std::string(" (exception location: ") + _file + ":" + std::to_string(_line) + "). Please report this error to arangodb.com";
|
||||
} else if (_code == TRI_ERROR_OUT_OF_MEMORY) {
|
||||
_errorMessage += std::string(" (exception location: ") + _file + ":" + std::to_string(_line) + ").";
|
||||
}
|
||||
|
||||
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2004-2014 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 ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Max Neunhoeffer
|
||||
/// @author Jan Steemann
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef ARANGODB_BASICS_FIXED_SIZE_ALLOCATOR_H
|
||||
#define ARANGODB_BASICS_FIXED_SIZE_ALLOCATOR_H 1
|
||||
|
||||
#include "Basics/Common.h"
|
||||
#include "Logger/Logger.h"
|
||||
|
||||
namespace arangodb {
|
||||
|
||||
class FixedSizeAllocator {
|
||||
private:
|
||||
|
||||
class MemoryBlock {
|
||||
public:
|
||||
MemoryBlock(MemoryBlock const&) = delete;
|
||||
MemoryBlock& operator=(MemoryBlock const&) = delete;
|
||||
|
||||
MemoryBlock(size_t itemSize, size_t nrItems)
|
||||
: _itemSize(itemSize), _nrAlloc(nrItems), _nrUsed(0), _alloc(nullptr), _data(nullptr) {
|
||||
|
||||
_alloc = new char[(itemSize * nrItems) + 64];
|
||||
|
||||
// adjust to cache line offset (assumed to be 64 bytes)
|
||||
_data = reinterpret_cast<char*>(
|
||||
(reinterpret_cast<uintptr_t>(_alloc) + 63) & ~((uintptr_t)0x3fu));
|
||||
}
|
||||
|
||||
MemoryBlock(MemoryBlock&& other)
|
||||
: _itemSize(other._itemSize), _nrAlloc(other._nrAlloc), _nrUsed(other._nrUsed), _alloc(other._alloc), _data(other._data) {
|
||||
other._nrAlloc = 0;
|
||||
other._nrUsed = 0;
|
||||
other._alloc = nullptr;
|
||||
other._data = nullptr;
|
||||
}
|
||||
|
||||
MemoryBlock& operator=(MemoryBlock&& other) {
|
||||
if (this != &other) {
|
||||
TRI_ASSERT(_itemSize == other._itemSize);
|
||||
|
||||
delete [] _alloc;
|
||||
_nrAlloc = other._nrAlloc;
|
||||
_nrUsed = other._nrUsed;
|
||||
_alloc = other._alloc;
|
||||
_data = other._data;
|
||||
|
||||
other._nrAlloc = 0;
|
||||
other._nrUsed = 0;
|
||||
other._alloc = nullptr;
|
||||
other._data = nullptr;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
~MemoryBlock() {
|
||||
delete[] _alloc;
|
||||
}
|
||||
|
||||
void* next() {
|
||||
TRI_ASSERT(_nrUsed < _nrAlloc);
|
||||
return static_cast<void*>(_data + (_itemSize * _nrUsed++));
|
||||
}
|
||||
|
||||
inline bool full() const {
|
||||
return _nrUsed == _nrAlloc;
|
||||
}
|
||||
|
||||
size_t memoryUsage() const {
|
||||
return (_data - _alloc) + _itemSize * _nrAlloc;
|
||||
}
|
||||
|
||||
private:
|
||||
size_t const _itemSize;
|
||||
size_t _nrAlloc;
|
||||
size_t _nrUsed;
|
||||
char* _alloc;
|
||||
char* _data;
|
||||
};
|
||||
|
||||
public:
|
||||
FixedSizeAllocator(FixedSizeAllocator const&) = delete;
|
||||
FixedSizeAllocator& operator=(FixedSizeAllocator const&) = delete;
|
||||
|
||||
explicit FixedSizeAllocator(size_t itemSize)
|
||||
: _itemSize(itemSize), _freelist(nullptr) {
|
||||
_blocks.reserve(4);
|
||||
}
|
||||
|
||||
~FixedSizeAllocator() {}
|
||||
|
||||
void* allocate() {
|
||||
if (_freelist != nullptr) {
|
||||
void* element = _freelist;
|
||||
_freelist = *reinterpret_cast<void**>(_freelist);
|
||||
return element;
|
||||
}
|
||||
|
||||
if (_blocks.empty() || _blocks.back()->full()) {
|
||||
allocateBlock();
|
||||
}
|
||||
TRI_ASSERT(!_blocks.empty());
|
||||
TRI_ASSERT(!_blocks.back()->full());
|
||||
|
||||
return _blocks.back()->next();
|
||||
}
|
||||
|
||||
void deallocateAll() {
|
||||
_blocks.clear();
|
||||
_freelist = nullptr;
|
||||
}
|
||||
|
||||
void deallocate(void* value) noexcept {
|
||||
*reinterpret_cast<void**>(value) = _freelist;
|
||||
_freelist = value;
|
||||
}
|
||||
|
||||
size_t memoryUsage() const {
|
||||
size_t total = 0;
|
||||
for (auto const& it : _blocks) {
|
||||
total += it->memoryUsage();
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
private:
|
||||
void allocateBlock() {
|
||||
size_t const size = 128 << (std::min)(size_t(8), _blocks.size());
|
||||
auto block = std::make_unique<MemoryBlock>(_itemSize, size);
|
||||
_blocks.emplace_back(block.get());
|
||||
block.release();
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<MemoryBlock>> _blocks;
|
||||
size_t _itemSize;
|
||||
void* _freelist;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue