int TRI_InsertBlockerCompactorVocBase (TRI_vocbase_t* vocbase, double lifetime, TRI_voc_tick_t* id) { compaction_blocker_t blocker; int res; if (lifetime <= 0.0) { return TRI_ERROR_BAD_PARAMETER; } blocker._id = TRI_NewTickServer(); blocker._expires = TRI_microtime() + lifetime; LockCompaction(vocbase); res = TRI_PushBackVector(&vocbase->_compactionBlockers._data, &blocker); UnlockCompaction(vocbase); if (res != TRI_ERROR_NO_ERROR) { return res; } *id = blocker._id; return TRI_ERROR_NO_ERROR; }
TRI_general_cursor_t* TRI_CreateGeneralCursor (TRI_vocbase_t* vocbase, TRI_general_cursor_result_t* result, const bool doCount, const TRI_general_cursor_length_t batchSize, TRI_json_t* extra) { TRI_general_cursor_t* cursor; TRI_ASSERT(vocbase != NULL); cursor = (TRI_general_cursor_t*) TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_general_cursor_t), false); if (cursor == NULL) { return NULL; } cursor->_vocbase = vocbase; cursor->_store = vocbase->_cursors; cursor->_result = result; cursor->_extra = extra; // might be NULL cursor->_expires = TRI_microtime() + 3600; // default lifetime: 1h cursor->_id = TRI_NewTickServer(); // state cursor->_currentRow = 0; cursor->_length = result->getLength(result); cursor->_hasCount = doCount; cursor->_batchSize = batchSize; cursor->_usage._refCount = 0; cursor->_usage._isDeleted = false; // assign functions cursor->next = NextGeneralCursor; cursor->hasNext = HasNextGeneralCursor; cursor->hasCount = HasCountGeneralCursor; cursor->getBatchSize = GetBatchSizeGeneralCursor; cursor->getExtra = GetExtraGeneralCursor; cursor->free = TRI_FreeGeneralCursor; TRI_InitSpin(&cursor->_lock); TRI_LockSpin(&vocbase->_cursors->_lock); // TODO: check for errors here TRI_InsertKeyAssociativePointer(&vocbase->_cursors->_ids, &cursor->_id, cursor, true); TRI_UnlockSpin(&vocbase->_cursors->_lock); LOG_TRACE("created general cursor"); return cursor; }
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_voc_fid_t) TRI_NewTickServer(); 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((char*) &cm, TRI_COL_MARKER_HEADER, sizeof(TRI_col_header_marker_t)); cm.base._tick = (TRI_voc_tick_t) fid; 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; }