static bool CheckJournalDocumentCollection (TRI_document_collection_t* doc) { TRI_collection_t* base; TRI_datafile_t* journal; bool worked; size_t i; size_t n; worked = false; base = &doc->base.base; if (base->_state != TRI_COL_STATE_WRITE) { return false; } // ............................................................................. // the only thread MODIFYING the _journals variable is this thread, // therefore no locking is required to access the _journals // ............................................................................. TRI_LOCK_JOURNAL_ENTRIES_DOC_COLLECTION(doc); n = base->_journals._length; for (i = 0; i < n;) { journal = base->_journals._buffer[i]; if (journal->_full) { worked = true; LOG_DEBUG("closing full journal '%s'", journal->getName(journal)); TRI_CloseJournalPrimaryCollection(&doc->base, i); n = base->_journals._length; i = 0; } else { ++i; } } if (base->_journals._length == 0) { journal = TRI_CreateJournalDocumentCollection(doc); if (journal != NULL) { worked = true; LOG_DEBUG("created new journal '%s'", journal->getName(journal)); TRI_BROADCAST_JOURNAL_ENTRIES_DOC_COLLECTION(doc); } else { // an error occurred when creating the journal file LOG_ERROR("could not create journal file"); // we still must wake up the other thread from time to time, otherwise we'll deadlock TRI_BROADCAST_JOURNAL_ENTRIES_DOC_COLLECTION(doc); } } TRI_UNLOCK_JOURNAL_ENTRIES_DOC_COLLECTION(doc); return worked; }
static bool CheckJournalDocumentCollection (TRI_document_collection_t* document) { TRI_collection_t* base; TRI_datafile_t* journal; bool worked; size_t i; size_t n; worked = false; base = &document->base.base; if (base->_state != TRI_COL_STATE_WRITE) { return false; } // ............................................................................. // the only thread MODIFYING the _journals variable is this thread, // therefore no locking is required to access the _journals // ............................................................................. TRI_LOCK_JOURNAL_ENTRIES_DOC_COLLECTION(document); n = base->_journals._length; for (i = 0; i < n;) { journal = static_cast<TRI_datafile_t*>(base->_journals._buffer[i]); if (journal->_full) { worked = true; LOG_DEBUG("closing full journal '%s'", journal->getName(journal)); TRI_CloseJournalPrimaryCollection(&document->base, i); n = base->_journals._length; i = 0; } else { ++i; } } // create a new journal if we do not have one, AND, if there was a request to create one // (sometimes we don't need a journal, e.g. directly after db._create(collection); when // the collection is still empty) if (base->_journals._length == 0 && document->_requestedJournalSize > 0) { TRI_voc_size_t targetSize = document->base.base._info._maximalSize; if (document->_requestedJournalSize > 0 && document->_requestedJournalSize > targetSize) { targetSize = document->_requestedJournalSize; } journal = TRI_CreateJournalDocumentCollection(document, targetSize); if (journal != NULL) { worked = true; document->_requestedJournalSize = 0; document->_rotateRequested = false; LOG_DEBUG("created new journal '%s'", journal->getName(journal)); } else { // an error occurred when creating the journal file LOG_ERROR("could not create journal file"); } } else if (document->_rotateRequested) { // only a rotate was requested document->_rotateRequested = false; } // always broadcast, otherwise other threads waiting for the broadcast might deadlock! TRI_BROADCAST_JOURNAL_ENTRIES_DOC_COLLECTION(document); TRI_UNLOCK_JOURNAL_ENTRIES_DOC_COLLECTION(document); return worked; }