1
0
Fork 0

allow writing too big markers into collections if maximalJournalSize is bigger than current datafile's size

This commit is contained in:
Jan Steemann 2013-03-28 14:41:40 +01:00
parent ba0d608a25
commit 666eae6b41
6 changed files with 37 additions and 11 deletions

View File

@ -96,7 +96,7 @@ static TRI_datafile_t* SelectCompactor (TRI_document_collection_t* document,
datafile = document->base.base._compactors._buffer[i];
// try to reserve space
res = TRI_ReserveElementDatafile(datafile, size, result);
res = TRI_ReserveElementDatafile(datafile, size, result, document->base.base._info._maximalSize);
// in case of full datafile, try next
if (res == TRI_ERROR_NO_ERROR) {

View File

@ -804,7 +804,7 @@ TRI_datafile_t* TRI_CreateDatafile (char const* filename,
header._fid = fid;
// reserve space and write header to file
result = TRI_ReserveElementDatafile(datafile, header.base._size, &position);
result = TRI_ReserveElementDatafile(datafile, header.base._size, &position, 0);
if (result == TRI_ERROR_NO_ERROR) {
result = TRI_WriteCrcElementDatafile(datafile, position, &header.base, header.base._size, true);
@ -1119,11 +1119,16 @@ void TRI_FillCrcKeyMarkerDatafile (TRI_datafile_t* datafile,
////////////////////////////////////////////////////////////////////////////////
/// @brief reserves room for an element, advances the pointer
///
/// note: maximalJournalSize is the collection's maximalJournalSize property,
/// which may be different from the size of the current datafile
/// some callers do not set the value of maximalJournalSize
////////////////////////////////////////////////////////////////////////////////
int TRI_ReserveElementDatafile (TRI_datafile_t* datafile,
TRI_voc_size_t size,
TRI_df_marker_t** position) {
TRI_df_marker_t** position,
TRI_voc_size_t maximalJournalSize) {
*position = 0;
size = TRI_DF_ALIGN_BLOCK(size);
@ -1139,9 +1144,27 @@ int TRI_ReserveElementDatafile (TRI_datafile_t* datafile,
// check the maximal size
if (size + TRI_JOURNAL_OVERHEAD > datafile->_maximalSize) {
// marker is bigger than journal size.
// adding the marker to this datafile will not work
if (maximalJournalSize <= datafile->_maximalSize) {
// the collection property 'maximalJournalSize' is equal to
// or smaller than the size of this datafile
// creating a new file and writing the marker into it will not work either
return TRI_set_errno(TRI_ERROR_ARANGO_DOCUMENT_TOO_LARGE);
}
// if we get here, the collection's 'maximalJournalSize' property is
// higher than the size of this datafile.
// maybe the marker will fit into a new datafile with the bigger size?
if (size + TRI_JOURNAL_OVERHEAD > maximalJournalSize) {
// marker still won't fit
return TRI_set_errno(TRI_ERROR_ARANGO_DOCUMENT_TOO_LARGE);
}
// fall-through intentional
}
// add the marker, leave enough room for the footer
if (datafile->_currentSize + size + datafile->_footerSize > datafile->_maximalSize) {
datafile->_lastError = TRI_set_errno(TRI_ERROR_ARANGO_DATAFILE_FULL);
@ -1457,7 +1480,7 @@ int TRI_SealDatafile (TRI_datafile_t* datafile) {
// reserve space and write footer to file
datafile->_footerSize = 0;
res = TRI_ReserveElementDatafile(datafile, footer.base._size, &position);
res = TRI_ReserveElementDatafile(datafile, footer.base._size, &position, 0);
if (res == TRI_ERROR_NO_ERROR) {
res = TRI_WriteCrcElementDatafile(datafile, position, &footer.base, footer.base._size, true);

View File

@ -532,7 +532,8 @@ void TRI_FillCrcKeyMarkerDatafile (TRI_datafile_t* datafile,
int TRI_ReserveElementDatafile (TRI_datafile_t* datafile,
TRI_voc_size_t size,
TRI_df_marker_t** position);
TRI_df_marker_t** position,
TRI_voc_size_t maximalJournalSize);
////////////////////////////////////////////////////////////////////////////////
/// @brief writes a marker to the datafile

View File

@ -601,7 +601,7 @@ static TRI_datafile_t* SelectJournal (TRI_document_collection_t* document,
datafile = base->_journals._buffer[i];
// try to reserve space
res = TRI_ReserveElementDatafile(datafile, size, result);
res = TRI_ReserveElementDatafile(datafile, size, result, document->base.base._info._maximalSize);
// in case of full datafile, try next
if (res == TRI_ERROR_NO_ERROR) {
@ -613,6 +613,8 @@ static TRI_datafile_t* SelectJournal (TRI_document_collection_t* document,
// some other error
TRI_UNLOCK_JOURNAL_ENTRIES_DOC_COLLECTION(document);
LOG_ERROR("cannot select datafile: '%s'", TRI_last_error());
return NULL;
}
}

View File

@ -171,7 +171,7 @@ static TRI_datafile_t* CreateJournal (TRI_primary_collection_t* primary,
// create a collection header, still in the temporary file
res = TRI_ReserveElementDatafile(journal, sizeof(TRI_col_header_marker_t), &position);
res = TRI_ReserveElementDatafile(journal, sizeof(TRI_col_header_marker_t), &position, primary->base._info._maximalSize);
if (res != TRI_ERROR_NO_ERROR) {
collection->_lastError = journal->_lastError;

View File

@ -132,7 +132,7 @@ static bool CreateJournal (TRI_shape_collection_t* collection) {
// create a collection header
res = TRI_ReserveElementDatafile(journal, sizeof(TRI_col_header_marker_t), &position);
res = TRI_ReserveElementDatafile(journal, sizeof(TRI_col_header_marker_t), &position, 0);
if (res != TRI_ERROR_NO_ERROR) {
LOG_ERROR("cannot create document header in journal '%s': %s",
@ -262,7 +262,7 @@ static TRI_datafile_t* SelectJournal (TRI_shape_collection_t* collection,
datafile = collection->base._journals._buffer[0];
// try to reserve space
res = TRI_ReserveElementDatafile(datafile, size, result);
res = TRI_ReserveElementDatafile(datafile, size, result, 0);
while (res == TRI_ERROR_ARANGO_DATAFILE_FULL) {
ok = CloseJournal(collection, datafile);
@ -280,7 +280,7 @@ static TRI_datafile_t* SelectJournal (TRI_shape_collection_t* collection,
datafile = collection->base._journals._buffer[0];
res = TRI_ReserveElementDatafile(datafile, size, result);
res = TRI_ReserveElementDatafile(datafile, size, result, 0);
}
if (res != TRI_ERROR_NO_ERROR) {