mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of github.com:arangodb/arangodb into vpack
This commit is contained in:
commit
b31cc0ba15
|
@ -839,10 +839,14 @@ Json AqlValue::extractObjectMember(
|
|||
|
||||
if (found != nullptr) {
|
||||
if (copy) {
|
||||
auto c = TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, found);
|
||||
|
||||
if (c == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
// return a copy of the value
|
||||
return Json(TRI_UNKNOWN_MEM_ZONE,
|
||||
TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, found),
|
||||
arangodb::basics::Json::AUTOFREE);
|
||||
return Json(TRI_UNKNOWN_MEM_ZONE, c, arangodb::basics::Json::AUTOFREE);
|
||||
}
|
||||
|
||||
// return a pointer to the original value, without asking for its
|
||||
|
@ -968,10 +972,13 @@ Json AqlValue::extractArrayMember(arangodb::AqlTransaction* trx,
|
|||
|
||||
if (found != nullptr) {
|
||||
if (copy) {
|
||||
auto c = TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, found);
|
||||
|
||||
if (c == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
// return a copy of the value
|
||||
return Json(TRI_UNKNOWN_MEM_ZONE,
|
||||
TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, found),
|
||||
arangodb::basics::Json::AUTOFREE);
|
||||
return Json(TRI_UNKNOWN_MEM_ZONE, c, arangodb::basics::Json::AUTOFREE);
|
||||
}
|
||||
|
||||
// return a pointer to the original value, without asking for its
|
||||
|
|
|
@ -145,7 +145,6 @@ static bool AllocateSlotList(TRI_fulltext_handles_t* const handles,
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create a handles instance
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -273,6 +272,7 @@ TRI_fulltext_handles_t* TRI_CompactHandleFulltextIndex(
|
|||
}
|
||||
|
||||
originalSlot = original->_slots[i];
|
||||
|
||||
for (j = start; j < originalSlot->_numUsed; ++j) {
|
||||
if (originalSlot->_deleted[j] == 1) {
|
||||
// printf("- setting map at #%lu to 0\n", (unsigned long) j);
|
||||
|
@ -325,11 +325,14 @@ TRI_fulltext_handle_t TRI_InsertHandleFulltextIndex(
|
|||
|
||||
if (!AllocateSlot(handles, slotNumber)) {
|
||||
// out of memory
|
||||
handles->_numSlots--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
slot = handles->_slots[slotNumber];
|
||||
|
||||
TRI_ASSERT(slot != nullptr);
|
||||
|
||||
// fill in document
|
||||
slot->_documents[slotPosition] = document;
|
||||
slot->_numUsed++;
|
||||
|
@ -365,6 +368,7 @@ bool TRI_DeleteDocumentHandleFulltextIndex(
|
|||
uint32_t j;
|
||||
|
||||
slot = handles->_slots[i];
|
||||
TRI_ASSERT(slot != nullptr);
|
||||
lastPosition = slot->_numUsed;
|
||||
|
||||
if (slot->_min > document || slot->_max < document ||
|
||||
|
@ -408,6 +412,8 @@ TRI_fulltext_doc_t TRI_GetDocumentFulltextIndex(
|
|||
#endif
|
||||
|
||||
slot = handles->_slots[slotNumber];
|
||||
TRI_ASSERT(slot != nullptr);
|
||||
|
||||
slotPosition = handle % handles->_slotSize;
|
||||
if (slot->_deleted[slotPosition]) {
|
||||
// document was deleted
|
||||
|
@ -426,16 +432,18 @@ void TRI_DumpHandleFulltextIndex(TRI_fulltext_handles_t* const handles) {
|
|||
uint32_t i;
|
||||
|
||||
for (i = 0; i < handles->_numSlots; ++i) {
|
||||
TRI_fulltext_handle_slot_t* slot;
|
||||
uint32_t j;
|
||||
TRI_fulltext_handle_slot_t* slot = handles->_slots[i];
|
||||
|
||||
slot = handles->_slots[i];
|
||||
if (slot == nullptr) {
|
||||
continue;
|
||||
}
|
||||
TRI_ASSERT(slot != nullptr);
|
||||
|
||||
printf("- slot %lu (%lu used, %lu deleted)\n", (unsigned long)i,
|
||||
(unsigned long)slot->_numUsed, (unsigned long)slot->_numDeleted);
|
||||
|
||||
// we're in a relevant slot. now check its documents
|
||||
for (j = 0; j < slot->_numUsed; ++j) {
|
||||
for (uint32_t j = 0; j < slot->_numUsed; ++j) {
|
||||
printf(" - #%lu %d %llu\n",
|
||||
(unsigned long)(i * handles->_slotSize + j),
|
||||
(int)slot->_deleted[j], (unsigned long long)slot->_documents[j]);
|
||||
|
|
|
@ -69,19 +69,23 @@ class SingleCollectionTransaction : public Transaction {
|
|||
TRI_vocbase_t* vocbase, std::string const& name,
|
||||
TRI_transaction_type_e accessType)
|
||||
: Transaction(transactionContext, vocbase, 0),
|
||||
_cid(this->resolver()->getCollectionId(name)),
|
||||
_cid(0),
|
||||
_trxCollection(nullptr),
|
||||
_documentCollection(nullptr),
|
||||
_accessType(accessType) {
|
||||
// add the (sole) collection
|
||||
this->addCollection(_cid, _accessType);
|
||||
if (setupState() == TRI_ERROR_NO_ERROR) {
|
||||
_cid = this->resolver()->getCollectionId(name);
|
||||
|
||||
this->addCollection(_cid, _accessType);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief end the transaction
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual ~SingleCollectionTransaction() {}
|
||||
~SingleCollectionTransaction() {}
|
||||
|
||||
|
||||
public:
|
||||
|
|
|
@ -107,6 +107,8 @@ class SingleCollectionWriteTransaction : public SingleCollectionTransaction {
|
|||
|
||||
int createDocument(TRI_doc_mptr_copy_t* mptr, TRI_json_t const* json,
|
||||
bool forceSync) {
|
||||
TRI_ASSERT(json != nullptr);
|
||||
|
||||
#ifdef TRI_ENABLE_MAINTAINER_MODE
|
||||
if (_numWrites++ > N) {
|
||||
return TRI_ERROR_TRANSACTION_INTERNAL;
|
||||
|
@ -141,6 +143,8 @@ class SingleCollectionWriteTransaction : public SingleCollectionTransaction {
|
|||
|
||||
int createEdge(TRI_doc_mptr_copy_t* mptr, TRI_json_t const* json,
|
||||
bool forceSync, void const* data) {
|
||||
TRI_ASSERT(json != nullptr);
|
||||
|
||||
#ifdef TRI_ENABLE_MAINTAINER_MODE
|
||||
if (_numWrites++ > N) {
|
||||
return TRI_ERROR_TRANSACTION_INTERNAL;
|
||||
|
@ -217,6 +221,11 @@ class SingleCollectionWriteTransaction : public SingleCollectionTransaction {
|
|||
TRI_voc_rid_t* actualRevision) {
|
||||
std::unique_ptr<TRI_json_t> json(
|
||||
arangodb::basics::VelocyPackHelper::velocyPackToJson(slice));
|
||||
|
||||
if (json == nullptr) {
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return updateDocument(key, mptr, json.get(), policy, forceSync,
|
||||
expectedRevision, actualRevision);
|
||||
}
|
||||
|
@ -230,6 +239,8 @@ class SingleCollectionWriteTransaction : public SingleCollectionTransaction {
|
|||
TRI_json_t const* json, TRI_doc_update_policy_e policy,
|
||||
bool forceSync, TRI_voc_rid_t expectedRevision,
|
||||
TRI_voc_rid_t* actualRevision) {
|
||||
TRI_ASSERT(json != nullptr);
|
||||
|
||||
#ifdef TRI_ENABLE_MAINTAINER_MODE
|
||||
if (_numWrites++ > N) {
|
||||
return TRI_ERROR_TRANSACTION_INTERNAL;
|
||||
|
|
|
@ -432,6 +432,8 @@ class Transaction {
|
|||
int create(TRI_transaction_collection_t* trxCollection,
|
||||
TRI_doc_mptr_copy_t* mptr, TRI_json_t const* json,
|
||||
void const* data, bool forceSync) {
|
||||
TRI_ASSERT(json != nullptr);
|
||||
|
||||
TRI_voc_key_t key = nullptr;
|
||||
int res = DocumentHelper::getKey(json, &key);
|
||||
|
||||
|
@ -463,6 +465,11 @@ class Transaction {
|
|||
void const* data, bool forceSync) {
|
||||
std::unique_ptr<TRI_json_t> json(
|
||||
arangodb::basics::VelocyPackHelper::velocyPackToJson(slice));
|
||||
|
||||
if (json == nullptr) {
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return create(trxCollection, mptr, json.get(), data, forceSync);
|
||||
}
|
||||
|
||||
|
@ -546,15 +553,14 @@ class Transaction {
|
|||
return isLocked(trxCollection, type);
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return the setup state
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int setupState () { return _setupState; }
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return the collection
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -611,6 +617,10 @@ class Transaction {
|
|||
// invalid cid
|
||||
return registerError(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
if (_setupState != TRI_ERROR_NO_ERROR) {
|
||||
return _setupState;
|
||||
}
|
||||
|
||||
const TRI_transaction_status_e status = getStatus();
|
||||
|
||||
|
@ -636,6 +646,10 @@ class Transaction {
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int addCollection(std::string const& name, TRI_transaction_type_e type) {
|
||||
if (_setupState != TRI_ERROR_NO_ERROR) {
|
||||
return _setupState;
|
||||
}
|
||||
|
||||
if (!_isReal) {
|
||||
return addCollection(this->resolver()->getCollectionIdCluster(name),
|
||||
name.c_str(), type);
|
||||
|
|
|
@ -2359,6 +2359,11 @@ static void JS_PropertiesVocbaseCol(
|
|||
|
||||
TRI_json_t* json = TRI_CreateJsonCollectionInfo(base->_info);
|
||||
|
||||
if (json == nullptr) {
|
||||
ReleaseCollection(collection);
|
||||
TRI_V8_THROW_EXCEPTION(res);
|
||||
}
|
||||
|
||||
// now log the property changes
|
||||
res = TRI_ERROR_NO_ERROR;
|
||||
|
||||
|
@ -2849,6 +2854,12 @@ static void InsertEdgeCol(TRI_vocbase_col_t* col, uint32_t argOffset,
|
|||
col->_vocbase, col->_cid);
|
||||
|
||||
// extract from
|
||||
res = trx.setupState();
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
TRI_V8_THROW_EXCEPTION(res);
|
||||
}
|
||||
|
||||
res = TRI_ParseVertex(args, trx.resolver(), edge._fromCid, fromKey,
|
||||
args[argOffset]);
|
||||
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
#include "VocBase/document-collection.h"
|
||||
#include "Wal/LogfileManager.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief extracts an attribute id from a marker
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -298,8 +297,6 @@ static bool EqualNameKeyAttributePath(TRI_associative_pointer_t*,
|
|||
ee->_aidLength * sizeof(TRI_shape_aid_t));
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create a shaper
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -453,6 +450,11 @@ TRI_shape_pid_t VocShaper::lookupAttributePathByName(char const* name) {
|
|||
|
||||
char const* VocShaper::attributeNameShapePid(TRI_shape_pid_t pid) {
|
||||
TRI_shape_path_t const* path = lookupAttributePathByPid(pid);
|
||||
|
||||
if (path == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char const* e = (char const*)path;
|
||||
|
||||
return e + sizeof(TRI_shape_path_t) +
|
||||
|
@ -521,6 +523,22 @@ TRI_shape_aid_t VocShaper::findOrCreateAttributeByName(char const* name) {
|
|||
TRI_IF_FAILURE("ShaperWriteAttributeMarker") {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
|
||||
}
|
||||
|
||||
{
|
||||
// make room for one more element
|
||||
WRITE_LOCKER(_attributeIdsLock);
|
||||
if (! TRI_ReserveAssociativePointer(&_attributeIds, _attributeIds._nrUsed + 1)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// make room for one more element
|
||||
WRITE_LOCKER(_attributeNamesLock);
|
||||
if (! TRI_ReserveAssociativePointer(&_attributeNames, _attributeNames._nrUsed + 1)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// write marker into wal
|
||||
arangodb::wal::SlotInfoCopy slotInfo =
|
||||
|
@ -622,6 +640,14 @@ TRI_shape_t const* VocShaper::findShape(TRI_shape_t* shape, bool create) {
|
|||
THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
|
||||
}
|
||||
|
||||
{
|
||||
// make room for one more element
|
||||
WRITE_LOCKER(_shapeDictionaryLock);
|
||||
if (! TRI_ReserveAssociativePointer(&_shapeDictionary, _shapeDictionary._nrUsed + 1)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// write marker into wal
|
||||
arangodb::wal::SlotInfoCopy slotInfo =
|
||||
arangodb::wal::LogfileManager::instance()->allocateAndWrite(marker,
|
||||
|
@ -1186,6 +1212,24 @@ TRI_shape_path_t const* VocShaper::findShapePathByName(char const* name,
|
|||
name, len + 1);
|
||||
|
||||
TRI_Free(_memoryZone, aids);
|
||||
|
||||
{
|
||||
// make room for one more element
|
||||
WRITE_LOCKER(_attributePathsByNameLock);
|
||||
if (! TRI_ReserveAssociativePointer(&_attributePathsByName, _attributePathsByName._nrUsed + 1)) {
|
||||
TRI_Free(_memoryZone, result);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// make room for one more element
|
||||
WRITE_LOCKER(_attributePathsByPidLock);
|
||||
if (! TRI_ReserveAssociativePointer(&_attributePathsByPid, _attributePathsByPid._nrUsed + 1)) {
|
||||
TRI_Free(_memoryZone, result);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
WRITE_LOCKER(_attributePathsByNameLock);
|
||||
|
@ -1215,7 +1259,6 @@ TRI_shape_path_t const* VocShaper::findShapePathByName(char const* name,
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief temporary structure for attributes
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -40,8 +40,6 @@
|
|||
#include "VocBase/transaction.h"
|
||||
#include "VocBase/vocbase.h"
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief read a tick value from a JSON struct
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -1168,19 +1168,12 @@ static int DumpCollection(TRI_replication_dump_t* dump,
|
|||
bool withTicks, bool translateCollectionIds,
|
||||
bool failOnUnknown,
|
||||
arangodb::CollectionNameResolver* resolver) {
|
||||
TRI_string_buffer_t* buffer;
|
||||
TRI_voc_tick_t lastFoundTick;
|
||||
TRI_voc_tid_t lastTid;
|
||||
int res;
|
||||
bool hasMore;
|
||||
bool bufferFull;
|
||||
bool ignoreMarkers;
|
||||
|
||||
LOG_TRACE("dumping collection %llu, tick range %llu - %llu",
|
||||
(unsigned long long)document->_info.id(),
|
||||
(unsigned long long)dataMin, (unsigned long long)dataMax);
|
||||
|
||||
buffer = dump->_buffer;
|
||||
TRI_string_buffer_t* buffer = dump->_buffer;
|
||||
|
||||
std::vector<df_entry_t> datafiles;
|
||||
|
||||
|
@ -1191,20 +1184,18 @@ static int DumpCollection(TRI_replication_dump_t* dump,
|
|||
}
|
||||
|
||||
// setup some iteration state
|
||||
lastFoundTick = 0;
|
||||
lastTid = 0;
|
||||
res = TRI_ERROR_NO_ERROR;
|
||||
hasMore = true;
|
||||
bufferFull = false;
|
||||
ignoreMarkers = false;
|
||||
TRI_voc_tick_t lastFoundTick = 0;
|
||||
TRI_voc_tid_t lastTid = 0;
|
||||
int res = TRI_ERROR_NO_ERROR;
|
||||
bool hasMore = true;
|
||||
bool bufferFull = false;
|
||||
bool ignoreMarkers = false;
|
||||
|
||||
size_t const n = datafiles.size();
|
||||
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
df_entry_t const& e = datafiles[i];
|
||||
TRI_datafile_t const* datafile = e._data;
|
||||
char const* ptr;
|
||||
char const* end;
|
||||
|
||||
// we are reading from a journal that might be modified in parallel
|
||||
// so we must read-lock it
|
||||
|
@ -1214,7 +1205,8 @@ static int DumpCollection(TRI_replication_dump_t* dump,
|
|||
TRI_ASSERT(datafile->_isSealed);
|
||||
}
|
||||
|
||||
ptr = datafile->_data;
|
||||
char const* ptr = datafile->_data;
|
||||
char const* end;
|
||||
|
||||
if (res == TRI_ERROR_NO_ERROR) {
|
||||
// no error so far. start iterating
|
||||
|
@ -1354,7 +1346,6 @@ static int DumpCollection(TRI_replication_dump_t* dump,
|
|||
return res;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief dump data from a collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -917,6 +917,8 @@ static bool FillShapeValueArray(VocShaper* shaper, TRI_shape_value_t* dst,
|
|||
static bool FillShapeValueJson(VocShaper* shaper, TRI_shape_value_t* dst,
|
||||
TRI_json_t const* json, size_t level,
|
||||
bool create) {
|
||||
TRI_ASSERT(json != nullptr);
|
||||
|
||||
switch (json->_type) {
|
||||
case TRI_JSON_UNUSED:
|
||||
return false;
|
||||
|
@ -2043,6 +2045,8 @@ TRI_shaped_json_t* TRI_ShapedJsonVelocyPack(VocShaper* shaper,
|
|||
|
||||
TRI_shaped_json_t* TRI_ShapedJsonJson(VocShaper* shaper, TRI_json_t const* json,
|
||||
bool create) {
|
||||
TRI_ASSERT(json != nullptr);
|
||||
|
||||
TRI_shape_value_t dst;
|
||||
|
||||
dst._value = nullptr;
|
||||
|
|
|
@ -100,7 +100,6 @@ static bool ResizeAssociativePointer(TRI_associative_pointer_t* array,
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initializes an array
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -275,19 +274,15 @@ void* TRI_LookupByElementAssociativePointer(TRI_associative_pointer_t* array,
|
|||
|
||||
void* TRI_InsertElementAssociativePointer(TRI_associative_pointer_t* array,
|
||||
void* element, bool overwrite) {
|
||||
uint64_t hash;
|
||||
uint64_t i;
|
||||
void* old;
|
||||
|
||||
// check for out-of-memory
|
||||
if (array->_nrAlloc == array->_nrUsed) {
|
||||
if (array->_nrAlloc == array->_nrUsed || array->_nrAlloc == 0) {
|
||||
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// compute the hash
|
||||
hash = array->hashElement(array, element);
|
||||
i = hash % array->_nrAlloc;
|
||||
uint64_t hash = array->hashElement(array, element);
|
||||
uint64_t i = hash % array->_nrAlloc;
|
||||
|
||||
#ifdef TRI_INTERNAL_STATS
|
||||
// update statistics
|
||||
|
@ -303,7 +298,7 @@ void* TRI_InsertElementAssociativePointer(TRI_associative_pointer_t* array,
|
|||
#endif
|
||||
}
|
||||
|
||||
old = array->_table[i];
|
||||
void* old = array->_table[i];
|
||||
|
||||
// if we found an element, return
|
||||
if (old != nullptr) {
|
||||
|
@ -333,19 +328,15 @@ void* TRI_InsertElementAssociativePointer(TRI_associative_pointer_t* array,
|
|||
void* TRI_InsertKeyAssociativePointer(TRI_associative_pointer_t* array,
|
||||
void const* key, void* element,
|
||||
bool overwrite) {
|
||||
uint64_t hash;
|
||||
uint64_t i;
|
||||
void* old;
|
||||
|
||||
// check for out-of-memory
|
||||
if (array->_nrAlloc == array->_nrUsed) {
|
||||
if (array->_nrAlloc == array->_nrUsed || array->_nrAlloc == 0) {
|
||||
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// compute the hash
|
||||
hash = array->hashKey(array, key);
|
||||
i = hash % array->_nrAlloc;
|
||||
uint64_t hash = array->hashKey(array, key);
|
||||
uint64_t i = hash % array->_nrAlloc;
|
||||
|
||||
#ifdef TRI_INTERNAL_STATS
|
||||
// update statistics
|
||||
|
@ -361,7 +352,7 @@ void* TRI_InsertKeyAssociativePointer(TRI_associative_pointer_t* array,
|
|||
#endif
|
||||
}
|
||||
|
||||
old = array->_table[i];
|
||||
void* old = array->_table[i];
|
||||
|
||||
// if we found an element, return
|
||||
if (old != nullptr) {
|
||||
|
@ -392,22 +383,18 @@ void* TRI_InsertKeyAssociativePointer(TRI_associative_pointer_t* array,
|
|||
int TRI_InsertKeyAssociativePointer2(TRI_associative_pointer_t* array,
|
||||
void const* key, void* element,
|
||||
void const** found) {
|
||||
uint64_t hash;
|
||||
uint64_t i;
|
||||
void* old;
|
||||
|
||||
if (found != nullptr) {
|
||||
*found = nullptr;
|
||||
}
|
||||
|
||||
// check for out-of-memory
|
||||
if (array->_nrAlloc == array->_nrUsed) {
|
||||
if (array->_nrAlloc == array->_nrUsed || array->_nrAlloc == 0) {
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// compute the hash
|
||||
hash = array->hashKey(array, key);
|
||||
i = hash % array->_nrAlloc;
|
||||
uint64_t hash = array->hashKey(array, key);
|
||||
uint64_t i = hash % array->_nrAlloc;
|
||||
|
||||
#ifdef TRI_INTERNAL_STATS
|
||||
// update statistics
|
||||
|
@ -423,7 +410,7 @@ int TRI_InsertKeyAssociativePointer2(TRI_associative_pointer_t* array,
|
|||
#endif
|
||||
}
|
||||
|
||||
old = array->_table[i];
|
||||
void* old = array->_table[i];
|
||||
|
||||
// if we found an element, return
|
||||
if (old != nullptr) {
|
||||
|
@ -465,13 +452,13 @@ int TRI_InsertKeyAssociativePointer2(TRI_associative_pointer_t* array,
|
|||
|
||||
void* TRI_RemoveKeyAssociativePointer(TRI_associative_pointer_t* array,
|
||||
void const* key) {
|
||||
uint64_t hash;
|
||||
uint64_t i;
|
||||
uint64_t k;
|
||||
void* old;
|
||||
|
||||
hash = array->hashKey(array, key);
|
||||
i = hash % array->_nrAlloc;
|
||||
if (array->_nrUsed == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint64_t hash = array->hashKey(array, key);
|
||||
uint64_t i = hash % array->_nrAlloc;
|
||||
|
||||
#ifdef TRI_INTERNAL_STATS
|
||||
// update statistics
|
||||
|
@ -493,12 +480,12 @@ void* TRI_RemoveKeyAssociativePointer(TRI_associative_pointer_t* array,
|
|||
}
|
||||
|
||||
// remove item
|
||||
old = array->_table[i];
|
||||
void* old = array->_table[i];
|
||||
array->_table[i] = nullptr;
|
||||
array->_nrUsed--;
|
||||
|
||||
// and now check the following places for items to move here
|
||||
k = TRI_IncModU64(i, array->_nrAlloc);
|
||||
uint64_t k = TRI_IncModU64(i, array->_nrAlloc);
|
||||
|
||||
while (array->_table[k] != nullptr) {
|
||||
uint64_t j = array->hashElement(array, array->_table[k]) % array->_nrAlloc;
|
||||
|
|
|
@ -2051,114 +2051,113 @@ std::string TRI_GetTempPath() {
|
|||
#else
|
||||
|
||||
std::string TRI_GetTempPath() {
|
||||
>>>>>>> 3f93a75... fixed temp path to honor TMPDIR
|
||||
|
||||
// ..........................................................................
|
||||
// Unfortunately we generally have little control on whether or not the
|
||||
// application will be compiled with UNICODE defined. In some cases such as
|
||||
// this one, we attempt to cater for both. MS provides some methods which are
|
||||
// 'defined' for both, for example, GetTempPath (below) actually converts to
|
||||
// GetTempPathA (ascii) or GetTempPathW (wide characters or what MS call
|
||||
// unicode).
|
||||
// ..........................................................................
|
||||
// ..........................................................................
|
||||
// Unfortunately we generally have little control on whether or not the
|
||||
// application will be compiled with UNICODE defined. In some cases such as
|
||||
// this one, we attempt to cater for both. MS provides some methods which are
|
||||
// 'defined' for both, for example, GetTempPath (below) actually converts to
|
||||
// GetTempPathA (ascii) or GetTempPathW (wide characters or what MS call
|
||||
// unicode).
|
||||
// ..........................................................................
|
||||
|
||||
#define LOCAL_MAX_PATH_BUFFER 2049
|
||||
TCHAR tempFileName[LOCAL_MAX_PATH_BUFFER];
|
||||
TCHAR tempPathName[LOCAL_MAX_PATH_BUFFER];
|
||||
DWORD dwReturnValue = 0;
|
||||
UINT uReturnValue = 0;
|
||||
HANDLE tempFileHandle = INVALID_HANDLE_VALUE;
|
||||
BOOL ok;
|
||||
char* result;
|
||||
TCHAR tempFileName[LOCAL_MAX_PATH_BUFFER];
|
||||
TCHAR tempPathName[LOCAL_MAX_PATH_BUFFER];
|
||||
DWORD dwReturnValue = 0;
|
||||
UINT uReturnValue = 0;
|
||||
HANDLE tempFileHandle = INVALID_HANDLE_VALUE;
|
||||
BOOL ok;
|
||||
char* result;
|
||||
|
||||
// ..........................................................................
|
||||
// Attempt to locate the path where the users temporary files are stored
|
||||
// Note we are imposing a limit of 2048+1 characters for the maximum size of a
|
||||
// possible path
|
||||
// ..........................................................................
|
||||
// ..........................................................................
|
||||
// Attempt to locate the path where the users temporary files are stored
|
||||
// Note we are imposing a limit of 2048+1 characters for the maximum size of a
|
||||
// possible path
|
||||
// ..........................................................................
|
||||
|
||||
dwReturnValue = GetTempPath(LOCAL_MAX_PATH_BUFFER, tempPathName);
|
||||
dwReturnValue = GetTempPath(LOCAL_MAX_PATH_BUFFER, tempPathName);
|
||||
|
||||
if ((dwReturnValue > LOCAL_MAX_PATH_BUFFER) || (dwReturnValue == 0)) {
|
||||
// something wrong
|
||||
LOG_TRACE("GetTempPathA failed: LOCAL_MAX_PATH_BUFFER=%d:dwReturnValue=%d",
|
||||
LOCAL_MAX_PATH_BUFFER, dwReturnValue);
|
||||
// attempt to simply use the current directory
|
||||
_tcscpy(tempFileName, TEXT("."));
|
||||
}
|
||||
|
||||
// ...........................................................................
|
||||
// Having obtained the temporary path, we have to determine if we can actually
|
||||
// write to that directory
|
||||
// ...........................................................................
|
||||
|
||||
uReturnValue = GetTempFileName(tempPathName, TEXT("TRI_"), 0, tempFileName);
|
||||
|
||||
if (uReturnValue == 0) {
|
||||
LOG_TRACE("GetTempFileNameA failed");
|
||||
_tcscpy(tempFileName, TEXT("TRI_tempFile"));
|
||||
}
|
||||
|
||||
tempFileHandle = CreateFile((LPTSTR)tempFileName, // file name
|
||||
GENERIC_WRITE, // open for write
|
||||
0, // do not share
|
||||
NULL, // default security
|
||||
CREATE_ALWAYS, // overwrite existing
|
||||
FILE_ATTRIBUTE_NORMAL, // normal file
|
||||
NULL); // no template
|
||||
|
||||
if (tempFileHandle == INVALID_HANDLE_VALUE) {
|
||||
LOG_FATAL_AND_EXIT("Can not create a temporary file");
|
||||
}
|
||||
|
||||
ok = CloseHandle(tempFileHandle);
|
||||
|
||||
if (!ok) {
|
||||
LOG_FATAL_AND_EXIT("Can not close the handle of a temporary file");
|
||||
}
|
||||
|
||||
ok = DeleteFile(tempFileName);
|
||||
|
||||
if (!ok) {
|
||||
LOG_FATAL_AND_EXIT("Can not destroy a temporary file");
|
||||
}
|
||||
|
||||
// ...........................................................................
|
||||
// Whether or not UNICODE is defined, we assume that the temporary file name
|
||||
// fits in the ascii set of characters. This is a small compromise so that
|
||||
// temporary file names can be extra long if required.
|
||||
// ...........................................................................
|
||||
{
|
||||
size_t j;
|
||||
size_t pathSize = _tcsclen(tempPathName);
|
||||
char* temp = static_cast<char*>(
|
||||
TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, pathSize + 1, false));
|
||||
|
||||
if (temp == nullptr) {
|
||||
LOG_FATAL_AND_EXIT("Out of memory");
|
||||
if ((dwReturnValue > LOCAL_MAX_PATH_BUFFER) || (dwReturnValue == 0)) {
|
||||
// something wrong
|
||||
LOG_TRACE("GetTempPathA failed: LOCAL_MAX_PATH_BUFFER=%d:dwReturnValue=%d",
|
||||
LOCAL_MAX_PATH_BUFFER, dwReturnValue);
|
||||
// attempt to simply use the current directory
|
||||
_tcscpy(tempFileName, TEXT("."));
|
||||
}
|
||||
|
||||
for (j = 0; j < pathSize; ++j) {
|
||||
if (tempPathName[j] > 127) {
|
||||
LOG_FATAL_AND_EXIT("Invalid characters in temporary path name");
|
||||
// ...........................................................................
|
||||
// Having obtained the temporary path, we have to determine if we can actually
|
||||
// write to that directory
|
||||
// ...........................................................................
|
||||
|
||||
uReturnValue = GetTempFileName(tempPathName, TEXT("TRI_"), 0, tempFileName);
|
||||
|
||||
if (uReturnValue == 0) {
|
||||
LOG_TRACE("GetTempFileNameA failed");
|
||||
_tcscpy(tempFileName, TEXT("TRI_tempFile"));
|
||||
}
|
||||
|
||||
tempFileHandle = CreateFile((LPTSTR)tempFileName, // file name
|
||||
GENERIC_WRITE, // open for write
|
||||
0, // do not share
|
||||
NULL, // default security
|
||||
CREATE_ALWAYS, // overwrite existing
|
||||
FILE_ATTRIBUTE_NORMAL, // normal file
|
||||
NULL); // no template
|
||||
|
||||
if (tempFileHandle == INVALID_HANDLE_VALUE) {
|
||||
LOG_FATAL_AND_EXIT("Can not create a temporary file");
|
||||
}
|
||||
|
||||
ok = CloseHandle(tempFileHandle);
|
||||
|
||||
if (!ok) {
|
||||
LOG_FATAL_AND_EXIT("Can not close the handle of a temporary file");
|
||||
}
|
||||
|
||||
ok = DeleteFile(tempFileName);
|
||||
|
||||
if (!ok) {
|
||||
LOG_FATAL_AND_EXIT("Can not destroy a temporary file");
|
||||
}
|
||||
|
||||
// ...........................................................................
|
||||
// Whether or not UNICODE is defined, we assume that the temporary file name
|
||||
// fits in the ascii set of characters. This is a small compromise so that
|
||||
// temporary file names can be extra long if required.
|
||||
// ...........................................................................
|
||||
{
|
||||
size_t j;
|
||||
size_t pathSize = _tcsclen(tempPathName);
|
||||
char* temp = static_cast<char*>(
|
||||
TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, pathSize + 1, false));
|
||||
|
||||
if (temp == nullptr) {
|
||||
LOG_FATAL_AND_EXIT("Out of memory");
|
||||
}
|
||||
temp[j] = (char)(tempPathName[j]);
|
||||
|
||||
for (j = 0; j < pathSize; ++j) {
|
||||
if (tempPathName[j] > 127) {
|
||||
LOG_FATAL_AND_EXIT("Invalid characters in temporary path name");
|
||||
}
|
||||
temp[j] = (char)(tempPathName[j]);
|
||||
}
|
||||
temp[pathSize] = 0;
|
||||
|
||||
// remove trailing directory separator
|
||||
RemoveTrailingSeparator(temp);
|
||||
|
||||
// ok = (WideCharToMultiByte(CP_UTF8, WC_NO_BEST_FIT_CHARS, tempPathName,
|
||||
// -1, temp, pathSize + 1, NULL, NULL) != 0);
|
||||
|
||||
result = TRI_DuplicateString(temp);
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, temp);
|
||||
}
|
||||
temp[pathSize] = 0;
|
||||
|
||||
// remove trailing directory separator
|
||||
RemoveTrailingSeparator(temp);
|
||||
|
||||
// ok = (WideCharToMultiByte(CP_UTF8, WC_NO_BEST_FIT_CHARS, tempPathName,
|
||||
// -1, temp, pathSize + 1, NULL, NULL) != 0);
|
||||
|
||||
result = TRI_DuplicateString(temp);
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, temp);
|
||||
}
|
||||
|
||||
std::string r = result;
|
||||
TRI_FreeString(TRI_CORE_MEM_ZONE, result);
|
||||
return r;
|
||||
std::string r = result;
|
||||
TRI_FreeString(TRI_CORE_MEM_ZONE, result);
|
||||
return r;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -2274,8 +2273,8 @@ void TRI_SetUserTempPath(std::string const& path) { TempPath = path; }
|
|||
|
||||
std::string TRI_LocateInstallDirectory() {
|
||||
return TRI_LocateBinaryPath(nullptr) +
|
||||
std::string(1, TRI_DIR_SEPARATOR_CHAR) + ".." +
|
||||
string(1, TRI_DIR_SEPARATOR_CHAR);
|
||||
std::string(1, TRI_DIR_SEPARATOR_CHAR) + ".." +
|
||||
std::string(1, TRI_DIR_SEPARATOR_CHAR);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -66,10 +66,19 @@ static TRI_json_t* MergeRecursive(TRI_memory_zone_t* zone,
|
|||
TRI_InitObjectJson(TRI_UNKNOWN_MEM_ZONE, &empty);
|
||||
TRI_json_t* merged = MergeRecursive(zone, &empty, value,
|
||||
nullMeansRemove, mergeObjects);
|
||||
|
||||
if (merged == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
TRI_Insert3ObjectJson(zone, r, key->_value._string.data, merged);
|
||||
} else {
|
||||
TRI_Insert3ObjectJson(zone, r, key->_value._string.data,
|
||||
TRI_CopyJson(zone, value));
|
||||
TRI_json_t* copy = TRI_CopyJson(zone, value);
|
||||
|
||||
if (copy == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TRI_Insert3ObjectJson(zone, r, key->_value._string.data, copy);
|
||||
}
|
||||
} else {
|
||||
// existing array already has the attribute => replace attribute
|
||||
|
@ -77,6 +86,9 @@ static TRI_json_t* MergeRecursive(TRI_memory_zone_t* zone,
|
|||
value->_type == TRI_JSON_OBJECT && mergeObjects) {
|
||||
TRI_json_t* merged = MergeRecursive(zone, lhsValue, value,
|
||||
nullMeansRemove, mergeObjects);
|
||||
if (merged == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
TRI_ReplaceObjectJson(zone, r, key->_value._string.data, merged);
|
||||
TRI_FreeJson(zone, merged);
|
||||
} else {
|
||||
|
|
|
@ -517,6 +517,8 @@ void TRI_InitObjectJson(TRI_memory_zone_t* zone, TRI_json_t* result,
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_DestroyJson(TRI_memory_zone_t* zone, TRI_json_t* object) {
|
||||
TRI_ASSERT(object != nullptr);
|
||||
|
||||
switch (object->_type) {
|
||||
case TRI_JSON_UNUSED:
|
||||
case TRI_JSON_NULL:
|
||||
|
@ -550,6 +552,7 @@ void TRI_DestroyJson(TRI_memory_zone_t* zone, TRI_json_t* object) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_FreeJson(TRI_memory_zone_t* zone, TRI_json_t* object) {
|
||||
TRI_ASSERT(object != nullptr);
|
||||
TRI_DestroyJson(zone, object);
|
||||
TRI_Free(zone, object);
|
||||
}
|
||||
|
@ -893,6 +896,8 @@ bool TRI_DeleteObjectJson(TRI_memory_zone_t* zone, TRI_json_t* object,
|
|||
|
||||
bool TRI_ReplaceObjectJson(TRI_memory_zone_t* zone, TRI_json_t* object,
|
||||
char const* name, TRI_json_t const* replacement) {
|
||||
TRI_ASSERT(replacement != nullptr);
|
||||
TRI_ASSERT(object != nullptr);
|
||||
TRI_ASSERT(object->_type == TRI_JSON_OBJECT);
|
||||
TRI_ASSERT(name != nullptr);
|
||||
|
||||
|
|
|
@ -506,6 +506,23 @@ int TRI_MapSystemError(DWORD error) {
|
|||
}
|
||||
}
|
||||
|
||||
static HANDLE hEventLog = INVALID_HANDLE_VALUE;
|
||||
|
||||
int TRI_InitWindowsEventLog(void) {
|
||||
hEventLog = RegisterEventSource(NULL, "ArangoDB");
|
||||
if (NULL == hEventLog) {
|
||||
// well, fail then.
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void TRI_CloseWindowsEventlog(void) {
|
||||
DeregisterEventSource(hEventLog);
|
||||
hEventLog = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief logs a message to the windows event log.
|
||||
/// we rather are keen on logging something at all then on being able to work
|
||||
|
@ -522,14 +539,10 @@ void TRI_LogWindowsEventlog(char const* func, char const* file, int line,
|
|||
char linebuf[32];
|
||||
LPCSTR logBuffers[] = {buf, file, func, linebuf, NULL};
|
||||
|
||||
HANDLE hEventLog = NULL;
|
||||
|
||||
hEventLog = RegisterEventSource(NULL, "ArangoDB");
|
||||
if (NULL == hEventLog) {
|
||||
// well, fail then.
|
||||
if (!TRI_InitWindowsEventLog()) {
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(linebuf, sizeof(linebuf), "%d", line);
|
||||
|
||||
DWORD len = _vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
|
||||
|
@ -541,7 +554,8 @@ void TRI_LogWindowsEventlog(char const* func, char const* file, int line,
|
|||
NULL)) {
|
||||
// well, fail then...
|
||||
}
|
||||
DeregisterEventSource(hEventLog);
|
||||
|
||||
TRI_CloseWindowsEventlog();
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue