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); }
static int WriteElement (TRI_shape_collection_t* collection, TRI_datafile_t* journal, TRI_df_marker_t* position, TRI_df_marker_t* marker, TRI_voc_size_t markerSize, void const* body, size_t bodySize) { int res; bool waitForSync; if (marker->_type == TRI_DF_MARKER_SHAPE) { // this is a shape. we will honor the collection's waitForSync attribute // which is determined by the global forceSyncShape flag and the actual collection's // waitForSync flag waitForSync = collection->base._info._waitForSync; } else { // this is an attribute. we will not sync the data now, but when the shape information // containing the attribute is written (that means we defer the sync until the TRI_DF_MARKER_SHAPE // marker is written) waitForSync = false; } res = TRI_WriteElementDatafile(journal, position, marker, markerSize, 0, 0, body, bodySize, waitForSync); if (res != TRI_ERROR_NO_ERROR) { collection->base._state = TRI_COL_STATE_WRITE_ERROR; } return res; }
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); }
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; }