uint32_t TRI_UInt32String (char const* str) { uint32_t result; char* endptr; #if defined(TRI_HAVE_STRTOUL_R) struct reent buffer; #elif defined(TRI_HAVE__STRTOUL_R) struct reent buffer; #endif TRI_set_errno(TRI_ERROR_NO_ERROR); #if defined(TRI_HAVE_STRTOUL_R) result = strtoul_r(&buffer, str, &endptr, 10); #elif defined(TRI_HAVE__STRTOUL_R) result = _strtoul_r(&buffer, str, &endptr, 10); #else result = strtoul(str, &endptr, 10); #endif while (isspace(*endptr)) { ++endptr; } if (*endptr != '\0') { TRI_set_errno(TRI_ERROR_ILLEGAL_NUMBER); } if (errno == ERANGE && (result == 0 || result == UINT32_MAX)) { TRI_set_errno(TRI_ERROR_NUMERIC_OVERFLOW); } return result; }
bool VelocyPackHelper::velocyPackToFile(char const* filename, VPackSlice const& slice, bool syncFile) { std::string const tmp = std::string(filename) + ".tmp"; // remove a potentially existing temporary file if (TRI_ExistsFile(tmp.c_str())) { TRI_UnlinkFile(tmp.c_str()); } int fd = TRI_CREATE(tmp.c_str(), O_CREAT | O_TRUNC | O_EXCL | O_RDWR | TRI_O_CLOEXEC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); if (fd < 0) { TRI_set_errno(TRI_ERROR_SYS_ERROR); LOG(ERR) << "cannot create json file '" << tmp << "': " << TRI_LAST_ERROR_STR; return false; } if (!PrintVelocyPack(fd, slice, true)) { TRI_CLOSE(fd); TRI_set_errno(TRI_ERROR_SYS_ERROR); LOG(ERR) << "cannot write to json file '" << tmp << "': " << TRI_LAST_ERROR_STR; TRI_UnlinkFile(tmp.c_str()); return false; } if (syncFile) { LOG(TRACE) << "syncing tmp file '" << tmp << "'"; if (!TRI_fsync(fd)) { TRI_CLOSE(fd); TRI_set_errno(TRI_ERROR_SYS_ERROR); LOG(ERR) << "cannot sync saved json '" << tmp << "': " << TRI_LAST_ERROR_STR; TRI_UnlinkFile(tmp.c_str()); return false; } } int res = TRI_CLOSE(fd); if (res < 0) { TRI_set_errno(TRI_ERROR_SYS_ERROR); LOG(ERR) << "cannot close saved file '" << tmp << "': " << TRI_LAST_ERROR_STR; TRI_UnlinkFile(tmp.c_str()); return false; } res = TRI_RenameFile(tmp.c_str(), filename); if (res != TRI_ERROR_NO_ERROR) { TRI_set_errno(res); LOG(ERR) << "cannot rename saved file '" << tmp << "' to '" << filename << "': " << TRI_LAST_ERROR_STR; TRI_UnlinkFile(tmp.c_str()); return false; } return true; }
TRI_replication_applier_t* TRI_CreateReplicationApplier (TRI_vocbase_t* vocbase) { TRI_replication_applier_t* applier; int res; applier = TRI_Allocate(TRI_CORE_MEM_ZONE, sizeof(TRI_replication_applier_t), false); if (applier == NULL) { return NULL; } TRI_InitConfigurationReplicationApplier(&applier->_configuration); TRI_InitStateReplicationApplier(&applier->_state); res = LoadConfiguration(vocbase, &applier->_configuration); if (res != TRI_ERROR_NO_ERROR && res != TRI_ERROR_FILE_NOT_FOUND) { TRI_set_errno(res); TRI_DestroyStateReplicationApplier(&applier->_state); TRI_DestroyConfigurationReplicationApplier(&applier->_configuration); TRI_Free(TRI_CORE_MEM_ZONE, applier); return NULL; } res = TRI_LoadStateReplicationApplier(vocbase, &applier->_state); if (res != TRI_ERROR_NO_ERROR && res != TRI_ERROR_FILE_NOT_FOUND) { TRI_set_errno(res); TRI_DestroyStateReplicationApplier(&applier->_state); TRI_DestroyConfigurationReplicationApplier(&applier->_configuration); TRI_Free(TRI_CORE_MEM_ZONE, applier); return NULL; } TRI_InitReadWriteLock(&applier->_statusLock); TRI_InitSpin(&applier->_threadLock); TRI_InitCondition(&applier->_runStateChangeCondition); applier->_vocbase = vocbase; applier->_databaseName = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, vocbase->_name); SetTerminateFlag(applier, false); assert(applier->_databaseName != NULL); TRI_SetProgressReplicationApplier(applier, "applier created", false); return applier; }
char* TRI_GetDirectoryCollection (char const* path, const TRI_col_info_t* const parameter) { char* filename; assert(path); assert(parameter); // shape collections use just the name, e.g. path/SHAPES if (parameter->_type == TRI_COL_TYPE_SHAPE) { filename = TRI_Concatenate2File(path, parameter->_name); } // other collections use the collection identifier else if (TRI_IS_DOCUMENT_COLLECTION(parameter->_type)) { char* tmp1; char* tmp2; tmp1 = TRI_StringUInt64(parameter->_cid); if (tmp1 == NULL) { TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY); return NULL; } tmp2 = TRI_Concatenate2String("collection-", tmp1); if (tmp2 == NULL) { TRI_FreeString(TRI_CORE_MEM_ZONE, tmp1); TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY); return NULL; } filename = TRI_Concatenate2File(path, tmp2); TRI_FreeString(TRI_CORE_MEM_ZONE, tmp1); TRI_FreeString(TRI_CORE_MEM_ZONE, tmp2); } // oops, unknown collection type else { TRI_set_errno(TRI_ERROR_ARANGO_UNKNOWN_COLLECTION_TYPE); return NULL; } if (filename == NULL) { TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY); } // might be NULL return filename; }
bool TRI_StartThread (TRI_thread_t* thread, TRI_tid_t* threadId, char const* name, void (*starter)(void*), void* data) { thread_data_t* d = static_cast<thread_data_t*>(TRI_Allocate(TRI_CORE_MEM_ZONE, sizeof(thread_data_t), false)); d->starter = starter; d->_data = data; d->_name = TRI_DuplicateString(name); int rc = pthread_create(thread, 0, &ThreadStarter, d); if (rc != 0) { TRI_set_errno(TRI_ERROR_SYS_ERROR); LOG_ERROR("could not start thread: %s", strerror(errno)); TRI_Free(TRI_CORE_MEM_ZONE, d); return false; } if (threadId != nullptr) { *threadId = (TRI_tid_t) *thread; } return true; }
static int CopyDocument (TRI_sim_collection_t* collection, TRI_df_marker_t const* marker, TRI_df_marker_t** result, TRI_voc_fid_t* fid) { TRI_datafile_t* journal; TRI_voc_size_t total; // find and select a journal total = marker->_size; journal = SelectCompactor(collection, total, result); if (journal == NULL) { collection->base.base._lastError = TRI_set_errno(TRI_ERROR_ARANGO_NO_JOURNAL); return false; } *fid = journal->_fid; // and write marker and blob return TRI_WriteElementDatafile(journal, *result, marker, marker->_size, NULL, 0, false); }
int TRI_AddLinkedArray (TRI_linked_array_t* array, void const* data) { TRI_linked_list_entry_t* entry; TRI_linked_list_entry_t* found; // create entry entry = TRI_Allocate(array->_memoryZone, sizeof(TRI_linked_list_entry_t), false); if (entry == NULL) { return TRI_ERROR_OUT_OF_MEMORY; } entry->_data = data; // insert to lookup table found = TRI_InsertElementAssociativePointer(&array->_array, entry, true); if (TRI_errno() == TRI_ERROR_OUT_OF_MEMORY) { TRI_Free(array->_memoryZone, entry); return TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY); } // this should not happen if (found != NULL) { TRI_RemoveLinkedList(&array->_list, found); TRI_Free(array->_memoryZone, found); } // add element at the beginning TRI_AddLinkedList(&array->_list, entry); return TRI_ERROR_NO_ERROR; }
TRI_shape_access_t* TRI_ShapeAccessor (TRI_shaper_t* shaper, TRI_shape_sid_t sid, TRI_shape_pid_t pid) { TRI_shape_access_t* accessor; bool ok; accessor = TRI_Allocate(shaper->_memoryZone, sizeof(TRI_shape_access_t), false); if (accessor == NULL) { TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY); return NULL; } accessor->_sid = sid; accessor->_pid = pid; accessor->_code = NULL; accessor->_memoryZone = shaper->_memoryZone; ok = BytecodeShapeAccessor(shaper, accessor); if (ok) { return accessor; } TRI_FreeShapeAccessor(accessor); return NULL; }
TRI_replication_applier_t* TRI_CreateReplicationApplier (TRI_server_t* server, TRI_vocbase_t* vocbase) { TRI_replication_applier_t* applier = new TRI_replication_applier_t(server, vocbase); if (applier == nullptr) { return nullptr; } TRI_InitConfigurationReplicationApplier(&applier->_configuration); TRI_InitStateReplicationApplier(&applier->_state); if (vocbase->_type == TRI_VOCBASE_TYPE_NORMAL) { int res = LoadConfiguration(vocbase, &applier->_configuration); if (res != TRI_ERROR_NO_ERROR && res != TRI_ERROR_FILE_NOT_FOUND) { TRI_set_errno(res); TRI_DestroyStateReplicationApplier(&applier->_state); TRI_DestroyConfigurationReplicationApplier(&applier->_configuration); delete applier; return nullptr; } res = TRI_LoadStateReplicationApplier(vocbase, &applier->_state); if (res != TRI_ERROR_NO_ERROR && res != TRI_ERROR_FILE_NOT_FOUND) { TRI_set_errno(res); TRI_DestroyStateReplicationApplier(&applier->_state); TRI_DestroyConfigurationReplicationApplier(&applier->_configuration); delete applier; return nullptr; } } SetTerminateFlag(applier, false); TRI_ASSERT(applier->_databaseName != nullptr); TRI_SetProgressReplicationApplier(applier, "applier created", false); return applier; }
void* TRI_AllocateZ (TRI_memory_zone_t* zone, uint64_t n, bool set, char const* file, int line) { #else void* TRI_Allocate (TRI_memory_zone_t* zone, uint64_t n, bool set) { #endif char* m; #ifdef TRI_ENABLE_MAINTAINER_MODE CheckSize(n, file, line); m = MALLOC_WRAPPER(zone, (size_t) n + sizeof(uintptr_t)); #else m = MALLOC_WRAPPER(zone, (size_t) n); #endif if (m == NULL) { if (zone->_failable) { TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY); return NULL; } if (CoreReserve == NULL) { fprintf(stderr, "FATAL: failed to allocate %llu bytes for memory zone %d" ZONE_DEBUG_LOCATION ", giving up!\n", (unsigned long long) n, (int) zone->_zid ZONE_DEBUG_PARAMS); TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL); } free(CoreReserve); CoreReserve = NULL; fprintf(stderr, "failed to allocate %llu bytes for memory zone %d" ZONE_DEBUG_LOCATION ", retrying!\n", (unsigned long long) n, (int) zone->_zid ZONE_DEBUG_PARAMS); #ifdef TRI_ENABLE_MAINTAINER_MODE return TRI_AllocateZ(zone, n, set, file, line); #else return TRI_Allocate(zone, n, set); #endif } #ifdef TRI_ENABLE_MAINTAINER_MODE else if (set) { memset(m, 0, (size_t) n + sizeof(uintptr_t)); } else { // prefill with 0xA5 (magic value, same as Valgrind will use) memset(m, 0xA5, (size_t) n + sizeof(uintptr_t)); } #else else if (set) {
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) { TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY); return NULL; } // compute the hash hash = array->hashKey(array, key); i = hash % array->_nrAlloc; #ifdef TRI_INTERNAL_STATS // update statistics array->_nrAdds++; #endif // search the table while (array->_table[i] != NULL && ! array->isEqualKeyElement(array, key, array->_table[i])) { i = TRI_IncModU64(i, array->_nrAlloc); #ifdef TRI_INTERNAL_STATS array->_nrProbesA++; #endif } old = array->_table[i]; // if we found an element, return if (old != NULL) { if (overwrite) { array->_table[i] = element; } return old; } // add a new element to the associative array array->_table[i] = element; array->_nrUsed++; // if we were adding and the table is more than half full, extend it if (array->_nrAlloc < 2 * array->_nrUsed) { ResizeAssociativePointer(array, (uint32_t) (2 * array->_nrAlloc) + 1); } return NULL; }
string slurp (string const& filename) { int fd = TRI_OPEN(filename.c_str(), O_RDONLY); if (fd == -1) { TRI_set_errno(errno); THROW_FILE_OPEN_ERROR("open", filename, "O_RDONLY", errno); } char buffer[10240]; StringBuffer result(TRI_CORE_MEM_ZONE); while (true) { ssize_t n = TRI_READ(fd, buffer, sizeof(buffer)); if (n == 0) { break; } if (n < 0) { TRI_set_errno(TRI_ERROR_SYS_ERROR); LOG_TRACE("read failed for '%s' with %s and result %d on fd %d", filename.c_str(), strerror(errno), (int) n, fd); TRI_CLOSE(fd); THROW_FILE_FUNC_ERROR("read", "", errno); } result.appendText(buffer, n); } TRI_CLOSE(fd); string r(result.c_str(), result.length()); return r; }
void* TRI_InsertKeyAssociativeSynced (TRI_associative_synced_t* array, void const* key, void* element) { uint64_t hash; uint64_t i; void* old; // check for out-of-memory if (array->_nrAlloc == array->_nrUsed) { TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY); return NULL; } // compute the hash hash = array->hashKey(array, key); i = hash % array->_nrAlloc; #ifdef TRI_INTERNAL_STATS // update statistics array->_nrAdds++; #endif // search the table TRI_WriteLockReadWriteLock(&array->_lock); while (array->_table[i] != NULL && ! array->isEqualKeyElement(array, key, array->_table[i])) { i = (i + 1) % array->_nrAlloc; #ifdef TRI_INTERNAL_STATS array->_nrProbesA++; #endif } old = array->_table[i]; // if we found an element, return if (old != NULL) { TRI_WriteUnlockReadWriteLock(&array->_lock); return old; } // add a new element to the associative array array->_table[i] = element; array->_nrUsed++; // if we were adding and the table is more than half full, extend it if (array->_nrAlloc < 2 * array->_nrUsed) { ResizeAssociativeSynced(array); } TRI_WriteUnlockReadWriteLock(&array->_lock); return NULL; }
void* TRI_AllocateZ(TRI_memory_zone_t* zone, uint64_t n, bool set, char const* file, int line) { #else void* TRI_Allocate(TRI_memory_zone_t* zone, uint64_t n, bool set) { #endif #ifdef ARANGODB_ENABLE_MAINTAINER_MODE CheckSize(n, file, line); #endif char* m = static_cast<char*>(MALLOC_WRAPPER(zone, (size_t)n)); if (m == nullptr) { if (zone->_failable) { TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY); return nullptr; } if (CoreReserve == nullptr) { fprintf(stderr, "FATAL: failed to allocate %llu bytes for core mem zone " ZONE_DEBUG_LOCATION ", giving up!\n", (unsigned long long)n ZONE_DEBUG_PARAMS); TRI_EXIT_FUNCTION(EXIT_FAILURE, nullptr); } free(CoreReserve); CoreReserve = nullptr; fprintf( stderr, "failed to allocate %llu bytes for core mem zone" ZONE_DEBUG_LOCATION ", retrying!\n", (unsigned long long)n ZONE_DEBUG_PARAMS); #ifdef ARANGODB_ENABLE_MAINTAINER_MODE return TRI_AllocateZ(zone, n, set, file, line); #else return TRI_Allocate(zone, n, set); #endif } if (set) { memset(m, 0, (size_t)n); } #ifdef ARANGODB_ENABLE_MAINTAINER_MODE else { // prefill with 0xA5 (magic value, same as Valgrind will use) memset(m, 0xA5, (size_t)n); } #endif return m; }
double TRI_DoubleString (char const* str) { double result; char* endptr; TRI_set_errno(TRI_ERROR_NO_ERROR); result = strtod(str, &endptr); while (isspace(*endptr)) { ++endptr; } if (*endptr != '\0') { TRI_set_errno(TRI_ERROR_ILLEGAL_NUMBER); } if (errno == ERANGE && (result == HUGE_VAL || result == -HUGE_VAL || result == 0)) { TRI_set_errno(TRI_ERROR_NUMERIC_OVERFLOW); } return result; }
uint64_t TRI_UInt64String (char const* str) { uint64_t result; char* endptr; #if defined(TRI_HAVE_STRTOULL_R) struct reent buffer; #elif defined(TRI_HAVE__STRTOULL_R) struct reent buffer; #endif TRI_set_errno(TRI_ERROR_NO_ERROR); #if defined(TRI_HAVE_STRTOULL_R) result = strtoull_r(&buffer, str, &endptr, 10); #elif defined(TRI_HAVE__STRTOULL_R) result = _strtoull_r(&buffer, str, &endptr, 10); #elif defined(TRI_HAVE_STRTOUI64) result = _strtoui64(str, &endptr, 10); #elif defined(TRI_HAVE_STRTOULL) result = strtoull(str, &endptr, 10); #else #warning cannot convert string to int64 #endif while (isspace(*endptr)) { ++endptr; } if (*endptr != '\0') { TRI_set_errno(TRI_ERROR_ILLEGAL_NUMBER); } if (errno == ERANGE && (result == 0 || result == UINT64_MAX)) { TRI_set_errno(TRI_ERROR_NUMERIC_OVERFLOW); } return result; }
void* TRI_InsertKeyAssociativeSynced (TRI_associative_synced_t* array, void const* key, void* element, bool overwrite) { uint64_t hash; uint64_t i; void* old; // compute the hash hash = array->hashKey(array, key); // search the table TRI_WriteLockReadWriteLock(&array->_lock); // check for out-of-memory if (array->_nrAlloc == array->_nrUsed && ! overwrite) { TRI_WriteUnlockReadWriteLock(&array->_lock); TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY); return NULL; } i = hash % array->_nrAlloc; while (array->_table[i] != NULL && ! array->isEqualKeyElement(array, key, array->_table[i])) { i = TRI_IncModU64(i, array->_nrAlloc); } old = array->_table[i]; // if we found an element, return if (old != NULL) { if (overwrite) { array->_table[i] = element; } TRI_WriteUnlockReadWriteLock(&array->_lock); return old; } // add a new element to the associative array array->_table[i] = element; array->_nrUsed++; // if we were adding and the table is more than half full, extend it if (array->_nrAlloc < 2 * array->_nrUsed) { ResizeAssociativeSynced(array, (uint32_t) (2 * array->_nrAlloc + 1)); } TRI_WriteUnlockReadWriteLock(&array->_lock); return NULL; }
bool TRI_InsertKeyAssociativeArray (TRI_associative_array_t* array, void* key, void* element, bool overwrite) { uint64_t hash; uint64_t i; // check for out-of-memory if (array->_nrAlloc == array->_nrUsed) { TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY); return false; } // compute the hash hash = array->hashKey(array, key); i = hash % array->_nrAlloc; #ifdef TRI_INTERNAL_STATS // update statistics array->_nrAdds++; #endif // search the table while (! array->isEmptyElement(array, array->_table + i * array->_elementSize) && ! array->isEqualKeyElement(array, key, array->_table + i * array->_elementSize)) { i = TRI_IncModU64(i, array->_nrAlloc); #ifdef TRI_INTERNAL_STATS array->_nrProbesA++; #endif } // if we found an element, return if (! array->isEmptyElement(array, array->_table + i * array->_elementSize)) { if (overwrite) { memcpy(array->_table + i * array->_elementSize, element, array->_elementSize); } return false; } // add a new element to the associative array memcpy(array->_table + i * array->_elementSize, element, array->_elementSize); array->_nrUsed++; // if we were adding and the table is more than half full, extend it if (array->_nrAlloc < 2 * array->_nrUsed) { ResizeAssociativeArray(array, (uint32_t) (2 * array->_nrAlloc + 1)); } return true; }
static int CopyMarker (TRI_document_collection_t* document, TRI_datafile_t* compactor, TRI_df_marker_t const* marker, TRI_df_marker_t** result) { int res; res = TRI_ReserveElementDatafile(compactor, marker->_size, result, 0); if (res != TRI_ERROR_NO_ERROR) { document->base.base._lastError = TRI_set_errno(TRI_ERROR_ARANGO_NO_JOURNAL); return TRI_ERROR_ARANGO_NO_JOURNAL; } return TRI_WriteElementDatafile(compactor, *result, marker, marker->_size, false); }
void TRI_InsertVector (TRI_vector_t* vector, void const* element, size_t position) { char* newBuffer; size_t newSize; // ........................................................................... // Check and see if we need to extend the vector // ........................................................................... if (vector->_length >= vector->_capacity || position >= vector->_length) { newSize = (size_t) (1 + (vector->_growthFactor * vector->_capacity)); if (position >= newSize) { newSize = position + 1; } newBuffer = (char*) TRI_Allocate(vector->_memoryZone, newSize * vector->_elementSize, false); if (newBuffer == NULL) { TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY); return; } vector->_capacity = newSize; if (vector->_buffer != NULL) { memcpy(newBuffer, vector->_buffer, vector->_length * vector->_elementSize); TRI_Free(vector->_memoryZone, vector->_buffer); } vector->_buffer = newBuffer; } if (position < vector->_length) { memmove(vector->_buffer + (vector->_elementSize * (position + 1)), vector->_buffer + (vector->_elementSize * position), vector->_elementSize * (vector->_length - position) ); vector->_length += 1; } else { vector->_length = position + 1; } memcpy(vector->_buffer + (vector->_elementSize * position), element, vector->_elementSize); }
TRI_headers_t* TRI_CreateSimpleHeaders (size_t headerSize) { simple_headers_t* headers = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(simple_headers_t), false); if (headers == NULL) { TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY); return NULL; } headers->base.request = RequestSimpleHeaders; headers->base.verify = VerifySimpleHeaders; headers->base.release = ReleaseSimpleHeaders; headers->_freelist = NULL; headers->_headerSize = headerSize; TRI_InitVectorPointer(&headers->_blocks, TRI_UNKNOWN_MEM_ZONE); return &headers->base; }
static TRI_doc_mptr_t* RequestSimpleHeaders (TRI_headers_t* h) { simple_headers_t* headers = (simple_headers_t*) h; char const* header; union { TRI_doc_mptr_t const* c; TRI_doc_mptr_t* h; } c; if (headers->_freelist == NULL) { char* begin; char* ptr; size_t blockSize; blockSize = GetBlockSize(headers->_blocks._length); begin = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, blockSize * headers->_headerSize, false); // out of memory if (begin == NULL) { TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY); return NULL; } ptr = begin + headers->_headerSize * (blockSize - 1); header = NULL; for (; begin <= ptr; ptr -= headers->_headerSize) { ClearSimpleHeaders((TRI_doc_mptr_t*) ptr, headers->_headerSize); ((TRI_doc_mptr_t*) ptr)->_data = header; header = ptr; } headers->_freelist = (TRI_doc_mptr_t*) header; TRI_PushBackVectorPointer(&headers->_blocks, begin); } c.c = headers->_freelist; headers->_freelist = c.c->_data; c.h->_data = NULL; return c.h; }
static int HashIndex_insert (TRI_hash_index_t* hashIndex, TRI_hash_index_element_t* element) { TRI_index_search_value_t key; int res; res = FillIndexSearchValueByHashIndexElement(hashIndex, &key, element); if (res != TRI_ERROR_NO_ERROR) { // out of memory return res; } res = TRI_InsertKeyHashArray(&hashIndex->_hashArray, &key, element, false); if (key._values != NULL) { TRI_Free(TRI_UNKNOWN_MEM_ZONE, key._values); } if (res == TRI_RESULT_KEY_EXISTS) { return TRI_set_errno(TRI_ERROR_ARANGO_UNIQUE_CONSTRAINT_VIOLATED); } return res; }
static TRI_doc_mptr_t CreateJson (TRI_doc_collection_t* collection, TRI_df_marker_type_e type, TRI_json_t const* json, void const* data, bool reuseId, bool release) { TRI_shaped_json_t* shaped; TRI_doc_mptr_t result; TRI_voc_did_t did = 0; TRI_voc_rid_t rid = 0; shaped = TRI_ShapedJsonJson(collection->_shaper, json); if (shaped == 0) { collection->base._lastError = TRI_set_errno(TRI_ERROR_ARANGO_SHAPER_FAILED); memset(&result, 0, sizeof(result)); return result; } if (reuseId && json != NULL && json->_type == TRI_JSON_ARRAY) { TRI_json_t* id = TRI_LookupArrayJson((TRI_json_t*) json, "_id"); TRI_json_t* rev = TRI_LookupArrayJson((TRI_json_t*) json, "_rev"); if (id != NULL && id->_type == TRI_JSON_NUMBER && rev != NULL && rev->_type == TRI_JSON_NUMBER) { // read existing document id and revision id from document did = (TRI_voc_did_t) id->_value._number; rid = (TRI_voc_rid_t) rev->_value._number; } } result = collection->create(collection, type, shaped, data, did, rid, release); TRI_FreeShapedJson(collection->_shaper, shaped); return result; }
TRI_shape_access_t* TRI_ShapeAccessor (TRI_shaper_t* shaper, TRI_shape_sid_t sid, TRI_shape_pid_t pid) { TRI_shape_access_t* accessor = static_cast<TRI_shape_access_t*>(TRI_Allocate(shaper->_memoryZone, sizeof(TRI_shape_access_t), false)); if (accessor == nullptr) { TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY); return nullptr; } accessor->_sid = sid; accessor->_pid = pid; accessor->_code = nullptr; accessor->_memoryZone = shaper->_memoryZone; bool ok = BytecodeShapeAccessor(shaper, accessor); if (ok) { return accessor; } TRI_FreeShapeAccessor(accessor); return nullptr; }
static TRI_doc_mptr_t UpdateJson (TRI_doc_collection_t* collection, TRI_json_t const* json, TRI_voc_did_t did, TRI_voc_rid_t rid, TRI_voc_rid_t* oldRid, TRI_doc_update_policy_e policy, bool release) { TRI_shaped_json_t* shaped; TRI_doc_mptr_t result; shaped = TRI_ShapedJsonJson(collection->_shaper, json); if (shaped == 0) { collection->base._lastError = TRI_set_errno(TRI_ERROR_ARANGO_SHAPER_FAILED); memset(&result, 0, sizeof(result)); return result; } result = collection->update(collection, shaped, did, rid, oldRid, policy, release); TRI_FreeShapedJson(collection->_shaper, shaped); return result; }
bool TRI_SaveJson (char const* filename, TRI_json_t const* object) { bool ok; char* tmp; int fd; int res; ssize_t m; tmp = TRI_Concatenate2String(filename, ".tmp"); if (tmp == NULL) { return false; } fd = TRI_CREATE(tmp, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR); if (fd < 0) { TRI_set_errno(TRI_ERROR_SYS_ERROR); LOG_ERROR("cannot create json file '%s': '%s'", tmp, TRI_LAST_ERROR_STR); TRI_FreeString(TRI_CORE_MEM_ZONE, tmp); return false; } ok = TRI_PrintJson(fd, object); if (! ok) { TRI_set_errno(TRI_ERROR_SYS_ERROR); LOG_ERROR("cannot write to json file '%s': '%s'", tmp, TRI_LAST_ERROR_STR); TRI_UnlinkFile(tmp); TRI_FreeString(TRI_CORE_MEM_ZONE, tmp); return false; } m = TRI_WRITE(fd, "\n", 1); if (m <= 0) { TRI_set_errno(TRI_ERROR_SYS_ERROR); LOG_ERROR("cannot write to json file '%s': '%s'", tmp, TRI_LAST_ERROR_STR); TRI_UnlinkFile(tmp); TRI_FreeString(TRI_CORE_MEM_ZONE, tmp); return false; } ok = TRI_fsync(fd); if (! ok) { TRI_set_errno(TRI_ERROR_SYS_ERROR); LOG_ERROR("cannot sync saved json '%s': '%s'", tmp, TRI_LAST_ERROR_STR); TRI_UnlinkFile(tmp); TRI_FreeString(TRI_CORE_MEM_ZONE, tmp); return false; } res = TRI_CLOSE(fd); if (res < 0) { TRI_set_errno(TRI_ERROR_SYS_ERROR); LOG_ERROR("cannot close saved file '%s': '%s'", tmp, TRI_LAST_ERROR_STR); TRI_UnlinkFile(tmp); TRI_FreeString(TRI_CORE_MEM_ZONE, tmp); return false; } res = TRI_RenameFile(tmp, filename); if (res != TRI_ERROR_NO_ERROR) { LOG_ERROR("cannot rename saved file '%s' to '%s': '%s'", tmp, filename, TRI_LAST_ERROR_STR); TRI_UnlinkFile(tmp); TRI_FreeString(TRI_CORE_MEM_ZONE, tmp); return res; } TRI_FreeString(TRI_CORE_MEM_ZONE, tmp); return ok; }
bool TRI_InitPQueue (TRI_pqueue_t* pq, size_t initialCapacity, size_t itemSize, bool reverse, void (*clearStorage) (struct TRI_pqueue_s*, void*), uint64_t (*getStorage) (struct TRI_pqueue_s*, void*), bool (*isLess) (struct TRI_pqueue_s*, void*, void*), void (*updateStorage) (struct TRI_pqueue_s*, void*, uint64_t pos)) { if (pq == NULL) { return false; } // .......................................................................... // Assign the call back functions // .......................................................................... // .......................................................................... // This callback is used to remove any memory which may be used as part of // the storage within the array _items. Callback required since we do not // know if there is any internal structure. // .......................................................................... pq->clearStoragePQ = clearStorage; // .......................................................................... // Returns the position within the _items array the element is. // Currently this simply is used to perform a consistency check. // .......................................................................... pq->getStoragePQ = getStorage; // .......................................................................... // The actual comparison function which returns true if left item is // less than right item (otherwise false). // .......................................................................... pq->isLessPQ = isLess; // .......................................................................... // Stores the position of the element within the _items array. Its purpose // is to allow the storage position to be located independent of the // priority queue _items array. // .......................................................................... pq->updateStoragePQ = updateStorage; // .......................................................................... // Assign the element size // .......................................................................... pq->_base._itemSize = itemSize; // .......................................................................... // Initialise invalid access counters // .......................................................................... pq->_base._nrFalseRemoves = 0; pq->_base._nrFalseAdds = 0; // .......................................................................... // Set the capacity and assign memory for storage // .......................................................................... pq->_base._capacity = initialCapacity; pq->_base._items = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, pq->_base._itemSize * pq->_base._capacity, true); if (pq->_base._items == NULL) { TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY); LOG_ERROR("out of memory when creating priority queue storage"); return false; } // .......................................................................... // initialise the number of items stored // .......................................................................... pq->_base._count = 0; // .......................................................................... // Determines if the pq should be reversed // .......................................................................... pq->_base._reverse = reverse; // .......................................................................... // The static call back functions to query, modifiy the pq // .......................................................................... pq->add = AddPQueue; pq->remove = RemovePQueue; pq->top = TopPQueue; return true; }
static int ExtractCurrentFile (unzFile uf, void* buffer, const size_t bufferSize, const char* outPath, const bool skipPaths, const bool overwrite, const char* password) { char filenameInZip[256]; char* filenameWithoutPath; char* fullPath; char* p; FILE *fout; unz_file_info64 fileInfo; if (unzGetCurrentFileInfo64(uf, &fileInfo, filenameInZip, sizeof(filenameInZip), NULL, 0, NULL, 0) != UNZ_OK) { return TRI_ERROR_INTERNAL; } p = filenameWithoutPath = filenameInZip; // get the file name without any path prefix while (*p != '\0') { if (*p == '/' || *p == '\\') { filenameWithoutPath = p + 1; } p++; } // found a directory if (*filenameWithoutPath == '\0') { if (! skipPaths) { fullPath = TRI_Concatenate2File(outPath, filenameInZip); TRI_CreateRecursiveDirectory(fullPath); TRI_Free(TRI_CORE_MEM_ZONE, fullPath); } } // found a file else { const char* writeFilename; if (! skipPaths) { writeFilename = filenameInZip; } else { writeFilename = filenameWithoutPath; } if (unzOpenCurrentFilePassword(uf, password) != UNZ_OK) { return TRI_ERROR_INTERNAL; } // prefix the name from the zip file with the path specified fullPath = TRI_Concatenate2File(outPath, writeFilename); if (! overwrite && TRI_ExistsFile(fullPath)) { return TRI_ERROR_INTERNAL; } // try to write the outfile fout = fopen(fullPath, "wb"); // cannot write to outfile. this may be due to the target directory missing if (fout == NULL && ! skipPaths && filenameWithoutPath != (char*) filenameInZip) { char* d; char c = *(filenameWithoutPath - 1); *(filenameWithoutPath - 1) = '\0'; // create target directory recursively d = TRI_Concatenate2File(outPath, filenameInZip); TRI_CreateRecursiveDirectory(d); TRI_Free(TRI_CORE_MEM_ZONE, d); *(filenameWithoutPath - 1) = c; // try again fout = fopen(fullPath, "wb"); } TRI_Free(TRI_CORE_MEM_ZONE, fullPath); if (fout == NULL) { return TRI_ERROR_CANNOT_WRITE_FILE; } while (true) { int result = unzReadCurrentFile(uf, buffer, bufferSize); if (result < 0) { fclose(fout); return TRI_ERROR_INTERNAL; } if (result > 0) { if (fwrite(buffer, result, 1, fout) != 1) { fclose(fout); return TRI_set_errno(TRI_ERROR_SYS_ERROR); } } else { assert(result == 0); break; } } fclose(fout); } unzCloseCurrentFile(uf); return TRI_ERROR_NO_ERROR; }
int TRI_ZipFile (const char* filename, const char* dir, TRI_vector_string_t const* files, const char* password) { void* buffer; size_t bufferSize; zipFile zf; #ifdef USEWIN32IOAPI zlib_filefunc64_def ffunc; #endif size_t i, n; int res; if (TRI_ExistsFile(filename)) { return TRI_ERROR_CANNOT_OVERWRITE_FILE; } bufferSize = 16384; buffer = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, bufferSize, false); if (buffer == NULL) { return TRI_ERROR_OUT_OF_MEMORY; } #ifdef USEWIN32IOAPI fill_win32_filefunc64A(&ffunc); zf = zipOpen2_64(filename, 0, NULL, &ffunc); #else zf = zipOpen64(filename, 0); #endif if (zf == NULL) { TRI_Free(TRI_UNKNOWN_MEM_ZONE, buffer); return ZIP_ERRNO; } res = TRI_ERROR_NO_ERROR; n = files->_length; for (i = 0; i < n; ++i) { FILE* fin; char* file; char* fullfile; char* saveName; zip_fileinfo zi; uint32_t crc; int isLarge; file = TRI_AtVectorString(files, i); if (*dir == '\0') { fullfile = TRI_DuplicateString(file); } else { fullfile = TRI_Concatenate2File(dir, file); } memset(&zi, 0, sizeof(zi)); res = TRI_Crc32File(fullfile, &crc); if (res != TRI_ERROR_NO_ERROR) { break; } isLarge = (TRI_SizeFile(file) > 0xFFFFFFFFLL); saveName = file; while (*saveName == '\\' || *saveName == '/') { ++saveName; } if (zipOpenNewFileInZip3_64(zf, saveName, &zi, NULL, 0, NULL, 0, NULL, /* comment*/ Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, password, (unsigned long) crc, isLarge) != ZIP_OK) { } fin = fopen(fullfile, "rb"); TRI_FreeString(TRI_CORE_MEM_ZONE, fullfile); if (fin == NULL) { break; } while (true) { int sizeRead; sizeRead = (int) fread(buffer, 1, bufferSize, fin); if (sizeRead < bufferSize) { if (feof(fin) == 0) { res = TRI_set_errno(TRI_ERROR_SYS_ERROR); break; } } if (sizeRead > 0) { res = zipWriteInFileInZip(zf, buffer, sizeRead); if (res != 0) { break; } } else if (sizeRead <= 0) { break; } } fclose(fin); zipCloseFileInZip(zf); if (res != TRI_ERROR_NO_ERROR) { break; } } zipClose(zf, NULL); TRI_Free(TRI_UNKNOWN_MEM_ZONE, buffer); return res; }