TRI_shape_collection_t* TRI_CreateShapeCollection (TRI_vocbase_t* vocbase, char const* path, TRI_col_info_t* parameter) { TRI_shape_collection_t* shape; TRI_collection_t* collection; shape = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_shape_collection_t), false); if (shape == NULL) { return NULL; } parameter->_type = TRI_COL_TYPE_SHAPE; parameter->_cid = TRI_NewTickVocBase(); parameter->_waitForSync = (vocbase->_forceSyncShapes || parameter->_waitForSync); collection = TRI_CreateCollection(vocbase, &shape->base, path, parameter); if (collection == NULL) { TRI_Free(TRI_UNKNOWN_MEM_ZONE, shape); return NULL; } TRI_InitMutex(&shape->_lock); return shape; }
int TRI_WriteShapeCollection (TRI_shape_collection_t* collection, TRI_df_marker_t* marker, TRI_voc_size_t markerSize, void const* body, TRI_voc_size_t bodySize, TRI_df_marker_t** result) { TRI_datafile_t* journal; int res; // generate a new tick marker->_tick = TRI_NewTickVocBase(); // lock the collection TRI_LockMutex(&collection->_lock); if (collection->base._state != TRI_COL_STATE_WRITE) { if (collection->base._state == TRI_COL_STATE_READ) { TRI_UnlockMutex(&collection->_lock); return TRI_ERROR_ARANGO_READ_ONLY; } TRI_UnlockMutex(&collection->_lock); return TRI_ERROR_ARANGO_ILLEGAL_STATE; } // find and select a journal journal = SelectJournal(collection, markerSize + bodySize, result); if (journal == NULL) { TRI_UnlockMutex(&collection->_lock); return TRI_ERROR_ARANGO_NO_JOURNAL; } // generate crc TRI_FillCrcMarkerDatafile(journal, marker, markerSize, 0, 0, body, bodySize); // and write marker and shape res = WriteElement(collection, journal, *result, marker, markerSize, body, bodySize); // release lock on collection TRI_UnlockMutex(&collection->_lock); return res; }
static TRI_shadow_t* CreateShadow (const void* const data) { TRI_shadow_t* shadow = (TRI_shadow_t*) TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_shadow_t), false); if (shadow == NULL) { return NULL; } shadow->_rc = 1; shadow->_data = (void*) data; shadow->_id = TRI_NewTickVocBase(); shadow->_deleted = false; shadow->_type = SHADOW_TRANSIENT; UpdateTimestampShadow(shadow); LOG_TRACE("created shadow %p with data ptr %p and id %llu", shadow, data, (unsigned long long) shadow->_id); return shadow; }
static TRI_datafile_t* CreateJournal (TRI_primary_collection_t* primary, bool compactor) { TRI_col_header_marker_t cm; TRI_collection_t* collection; TRI_datafile_t* journal; TRI_df_marker_t* position; int res; char* filename; collection = &primary->base; if (collection->_info._isVolatile) { // in-memory collection filename = NULL; } else { char* jname; char* number; // construct a suitable filename number = TRI_StringUInt64(TRI_NewTickVocBase()); if (compactor) { jname = TRI_Concatenate3String("journal-", number, ".db"); } else { jname = TRI_Concatenate3String("compactor-", number, ".db"); } filename = TRI_Concatenate2File(collection->_directory, jname); TRI_FreeString(TRI_CORE_MEM_ZONE, number); TRI_FreeString(TRI_CORE_MEM_ZONE, jname); } // create journal file journal = TRI_CreateDatafile(filename, collection->_info._maximalSize); if (filename != NULL) { TRI_FreeString(TRI_CORE_MEM_ZONE, filename); } if (journal == NULL) { if (TRI_errno() == TRI_ERROR_OUT_OF_MEMORY_MMAP) { collection->_lastError = TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY_MMAP); collection->_state = TRI_COL_STATE_READ; } else { collection->_lastError = TRI_set_errno(TRI_ERROR_ARANGO_NO_JOURNAL); collection->_state = TRI_COL_STATE_WRITE_ERROR; } return NULL; } LOG_TRACE("created a new primary journal '%s'", journal->getName(journal)); if (journal->isPhysical(journal)) { char* jname; char* number; bool ok; // and use the correct name number = TRI_StringUInt64(journal->_fid); if (compactor) { jname = TRI_Concatenate3String("compactor-", number, ".db"); } else { jname = TRI_Concatenate3String("journal-", number, ".db"); } filename = TRI_Concatenate2File(collection->_directory, jname); TRI_FreeString(TRI_CORE_MEM_ZONE, number); TRI_FreeString(TRI_CORE_MEM_ZONE, jname); ok = TRI_RenameDatafile(journal, filename); if (! ok) { LOG_WARNING("failed to rename the journal to '%s': %s", filename, TRI_last_error()); } else { LOG_TRACE("renamed journal to '%s'", filename); } TRI_FreeString(TRI_CORE_MEM_ZONE, filename); } // create a collection header res = TRI_ReserveElementDatafile(journal, sizeof(TRI_col_header_marker_t), &position); if (res != TRI_ERROR_NO_ERROR) { collection->_lastError = journal->_lastError; LOG_ERROR("cannot create document header in journal '%s': %s", journal->getName(journal), TRI_last_error()); TRI_FreeDatafile(journal); return NULL; } memset(&cm, 0, sizeof(cm)); cm.base._size = sizeof(TRI_col_header_marker_t); cm.base._type = TRI_COL_MARKER_HEADER; cm.base._tick = TRI_NewTickVocBase(); cm._cid = collection->_info._cid; TRI_FillCrcMarkerDatafile(journal, &cm.base, sizeof(cm), 0, 0, 0, 0); res = TRI_WriteElementDatafile(journal, position, &cm.base, sizeof(cm), 0, 0, 0, 0, true); if (res != TRI_ERROR_NO_ERROR) { collection->_lastError = journal->_lastError; LOG_ERROR("cannot create document header in journal '%s': %s", journal->getName(journal), TRI_last_error()); TRI_FreeDatafile(journal); return NULL; } // that's it if (compactor) { TRI_PushBackVectorPointer(&collection->_compactors, journal); } else { TRI_PushBackVectorPointer(&collection->_journals, journal); } return journal; }
static bool CreateJournal (TRI_shape_collection_t* collection) { TRI_col_header_marker_t cm; TRI_datafile_t* journal; TRI_df_marker_t* position; char* filename; int res; if (collection->base._info._isVolatile) { // in memory collection filename = NULL; } else { char* jname; char* number; number = TRI_StringUInt32(TRI_NewTickVocBase()); if (! number) { return false; } jname = TRI_Concatenate3String("journal-", number, ".db"); TRI_FreeString(TRI_CORE_MEM_ZONE, number); filename = TRI_Concatenate2File(collection->base._directory, jname); TRI_FreeString(TRI_CORE_MEM_ZONE, jname); } journal = TRI_CreateDatafile(filename, collection->base._info._maximalSize); if (filename != NULL) { TRI_FreeString(TRI_CORE_MEM_ZONE, filename); } // check that a journal was created if (journal == NULL) { if (TRI_errno() == TRI_ERROR_OUT_OF_MEMORY_MMAP) { collection->base._lastError = TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY_MMAP); collection->base._state = TRI_COL_STATE_READ; } else { collection->base._lastError = TRI_set_errno(TRI_ERROR_ARANGO_NO_JOURNAL); collection->base._state = TRI_COL_STATE_WRITE_ERROR; } return false; } LOG_TRACE("created a new shape journal '%s'", journal->getName(journal)); if (journal->isPhysical(journal)) { char* jname; char* number; bool ok; // and use the correct name number = TRI_StringUInt32(journal->_fid); jname = TRI_Concatenate3String("journal-", number, ".db"); filename = TRI_Concatenate2File(collection->base._directory, jname); TRI_FreeString(TRI_CORE_MEM_ZONE, number); TRI_FreeString(TRI_CORE_MEM_ZONE, jname); ok = TRI_RenameDatafile(journal, filename); if (! ok) { // TODO: remove disastrous call to exit() here LOG_FATAL_AND_EXIT("failed to rename the journal to '%s': %s", filename, TRI_last_error()); } else { LOG_TRACE("renamed journal to '%s'", filename); } TRI_FreeString(TRI_CORE_MEM_ZONE, filename); } // create a collection header res = TRI_ReserveElementDatafile(journal, sizeof(TRI_col_header_marker_t), &position); if (res != TRI_ERROR_NO_ERROR) { LOG_ERROR("cannot create document header in journal '%s': %s", journal->getName(journal), TRI_last_error()); TRI_FreeDatafile(journal); return false; } // create a header memset(&cm, 0, sizeof(cm)); cm.base._size = sizeof(TRI_col_header_marker_t); cm.base._type = TRI_COL_MARKER_HEADER; cm.base._tick = TRI_NewTickVocBase(); cm._cid = collection->base._info._cid; TRI_FillCrcMarkerDatafile(journal, &cm.base, sizeof(cm), 0, 0, 0, 0); // on journal creation, always use waitForSync = true res = TRI_WriteElementDatafile(journal, position, &cm.base, sizeof(cm), 0, 0, 0, 0, true); if (res != TRI_ERROR_NO_ERROR) { LOG_ERROR("cannot create document header in journal '%s': %s", journal->getName(journal), TRI_last_error()); TRI_FreeDatafile(journal); return false; } // that's it TRI_PushBackVectorPointer(&collection->base._journals, journal); return true; }
static TRI_datafile_t* CreateJournal (TRI_primary_collection_t* primary, TRI_voc_size_t maximalSize) { TRI_col_header_marker_t cm; TRI_collection_t* collection; TRI_datafile_t* journal; TRI_df_marker_t* position; TRI_voc_fid_t fid; int res; collection = &primary->base; fid = TRI_NewTickVocBase(); if (collection->_info._isVolatile) { // in-memory collection journal = TRI_CreateDatafile(NULL, fid, maximalSize); } else { char* jname; char* number; char* filename; // construct a suitable filename (which is temporary at the beginning) number = TRI_StringUInt64(fid); jname = TRI_Concatenate3String("temp-", number, ".db"); filename = TRI_Concatenate2File(collection->_directory, jname); TRI_FreeString(TRI_CORE_MEM_ZONE, number); TRI_FreeString(TRI_CORE_MEM_ZONE, jname); journal = TRI_CreateDatafile(filename, fid, maximalSize); TRI_FreeString(TRI_CORE_MEM_ZONE, filename); } if (journal == NULL) { if (TRI_errno() == TRI_ERROR_OUT_OF_MEMORY_MMAP) { collection->_lastError = TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY_MMAP); collection->_state = TRI_COL_STATE_READ; } else { collection->_lastError = TRI_set_errno(TRI_ERROR_ARANGO_NO_JOURNAL); collection->_state = TRI_COL_STATE_WRITE_ERROR; } return NULL; } LOG_TRACE("created new journal '%s'", journal->getName(journal)); // create a collection header, still in the temporary file res = TRI_ReserveElementDatafile(journal, sizeof(TRI_col_header_marker_t), &position, maximalSize); if (res != TRI_ERROR_NO_ERROR) { collection->_lastError = journal->_lastError; LOG_ERROR("cannot create document header in journal '%s': %s", journal->getName(journal), TRI_last_error()); TRI_FreeDatafile(journal); return NULL; } TRI_InitMarker(&cm.base, TRI_COL_MARKER_HEADER, sizeof(TRI_col_header_marker_t), TRI_NewTickVocBase()); cm._type = (TRI_col_type_t) collection->_info._type; cm._cid = collection->_info._cid; res = TRI_WriteCrcElementDatafile(journal, position, &cm.base, sizeof(cm), true); if (res != TRI_ERROR_NO_ERROR) { collection->_lastError = journal->_lastError; LOG_ERROR("cannot create document header in journal '%s': %s", journal->getName(journal), TRI_last_error()); TRI_FreeDatafile(journal); return NULL; } assert(fid == journal->_fid); // if a physical file, we can rename it from the temporary name to the correct name if (journal->isPhysical(journal)) { char* jname; char* number; char* filename; bool ok; // and use the correct name number = TRI_StringUInt64(journal->_fid); jname = TRI_Concatenate3String("journal-", number, ".db"); filename = TRI_Concatenate2File(collection->_directory, jname); TRI_FreeString(TRI_CORE_MEM_ZONE, number); TRI_FreeString(TRI_CORE_MEM_ZONE, jname); ok = TRI_RenameDatafile(journal, filename); if (! ok) { LOG_ERROR("failed to rename the journal to '%s': %s", filename, TRI_last_error()); TRI_FreeDatafile(journal); TRI_FreeString(TRI_CORE_MEM_ZONE, filename); return NULL; } else { LOG_TRACE("renamed journal from %s to '%s'", journal->getName(journal), filename); } TRI_FreeString(TRI_CORE_MEM_ZONE, filename); } TRI_PushBackVectorPointer(&collection->_journals, journal); return journal; }
static TRI_datafile_t* CreateCompactor (TRI_primary_collection_t* primary, TRI_voc_fid_t fid, TRI_voc_size_t maximalSize) { TRI_col_header_marker_t cm; TRI_collection_t* collection; TRI_datafile_t* journal; TRI_df_marker_t* position; int res; collection = &primary->base; if (collection->_info._isVolatile) { // in-memory collection journal = TRI_CreateDatafile(NULL, fid, maximalSize); } else { char* jname; char* number; char* filename; number = TRI_StringUInt64(fid); jname = TRI_Concatenate3String("compaction-", number, ".db"); filename = TRI_Concatenate2File(collection->_directory, jname); TRI_FreeString(TRI_CORE_MEM_ZONE, number); TRI_FreeString(TRI_CORE_MEM_ZONE, jname); if (TRI_ExistsFile(filename)) { // remove any existing temporary file first TRI_UnlinkFile(filename); } journal = TRI_CreateDatafile(filename, fid, maximalSize); TRI_FreeString(TRI_CORE_MEM_ZONE, filename); } if (journal == NULL) { if (TRI_errno() == TRI_ERROR_OUT_OF_MEMORY_MMAP) { collection->_lastError = TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY_MMAP); collection->_state = TRI_COL_STATE_READ; } else { collection->_lastError = TRI_set_errno(TRI_ERROR_ARANGO_NO_JOURNAL); collection->_state = TRI_COL_STATE_WRITE_ERROR; } return NULL; } LOG_TRACE("created new compactor '%s'", journal->getName(journal)); // create a collection header, still in the temporary file res = TRI_ReserveElementDatafile(journal, sizeof(TRI_col_header_marker_t), &position, maximalSize); if (res != TRI_ERROR_NO_ERROR) { collection->_lastError = journal->_lastError; LOG_ERROR("cannot create document header in compactor '%s': %s", journal->getName(journal), TRI_last_error()); TRI_FreeDatafile(journal); return NULL; } TRI_InitMarker(&cm.base, TRI_COL_MARKER_HEADER, sizeof(TRI_col_header_marker_t), TRI_NewTickVocBase()); cm._type = (TRI_col_type_t) collection->_info._type; cm._cid = collection->_info._cid; res = TRI_WriteCrcElementDatafile(journal, position, &cm.base, sizeof(cm), true); if (res != TRI_ERROR_NO_ERROR) { collection->_lastError = journal->_lastError; LOG_ERROR("cannot create document header in compactor '%s': %s", journal->getName(journal), TRI_last_error()); TRI_FreeDatafile(journal); return NULL; } assert(fid == journal->_fid); return journal; }