1
0
Fork 0

Merge branch 'devel' of github.com:arangodb/arangodb into vpack

This commit is contained in:
Michael Hackstein 2016-01-22 13:36:47 +01:00
commit b31cc0ba15
15 changed files with 290 additions and 182 deletions

View File

@ -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

View File

@ -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]);

View File

@ -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:

View File

@ -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;

View File

@ -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);

View File

@ -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]);

View File

@ -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
////////////////////////////////////////////////////////////////////////////////

View File

@ -40,8 +40,6 @@
#include "VocBase/transaction.h"
#include "VocBase/vocbase.h"
////////////////////////////////////////////////////////////////////////////////
/// @brief read a tick value from a JSON struct
////////////////////////////////////////////////////////////////////////////////

View File

@ -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
////////////////////////////////////////////////////////////////////////////////

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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 {

View File

@ -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);

View File

@ -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();
}