mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of github.com:triAGENS/ArangoDB into devel
This commit is contained in:
commit
76a73b166f
|
@ -115,8 +115,8 @@ static int PostInsertCapConstraint (TRI_index_t* idx,
|
|||
|
||||
LOG_DEBUG("removing document '%s' because of cap constraint", (char*) oldest->_key);
|
||||
|
||||
TRI_InitContextPrimaryCollection(&rollbackContext, primary, TRI_DOC_UPDATE_LAST_WRITE, false);
|
||||
res = TRI_DeleteDocumentDocumentCollection(&rollbackContext, oldest);
|
||||
TRI_InitContextPrimaryCollection(&rollbackContext, primary);
|
||||
res = TRI_DeleteDocumentDocumentCollection(&rollbackContext, NULL, oldest);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
LOG_WARNING("cannot cap collection: %s", TRI_last_error());
|
||||
|
|
|
@ -96,6 +96,7 @@ bin_arangod_SOURCES = \
|
|||
arangod/VocBase/shape-collection.c \
|
||||
arangod/VocBase/synchroniser.c \
|
||||
arangod/VocBase/transaction.c \
|
||||
arangod/VocBase/update-policy.c \
|
||||
arangod/VocBase/voc-shaper.c \
|
||||
arangod/VocBase/vocbase.c
|
||||
|
||||
|
|
|
@ -665,9 +665,12 @@ static bool IsEqualKeyElementPQIndex(TRI_associative_array_t* aa, void* key, voi
|
|||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
||||
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "VocBase/barrier.h"
|
||||
#include "VocBase/document-collection.h"
|
||||
#include "VocBase/transaction.h"
|
||||
#include "VocBase/update-policy.h"
|
||||
#include "VocBase/vocbase.h"
|
||||
|
||||
#include "BasicsC/random.h"
|
||||
|
@ -452,7 +453,7 @@ namespace triagens {
|
|||
const string& key,
|
||||
const bool lock) {
|
||||
TRI_doc_operation_context_t context;
|
||||
TRI_InitReadContextPrimaryCollection(&context, primary);
|
||||
TRI_InitContextPrimaryCollection(&context, primary);
|
||||
|
||||
if (lock) {
|
||||
// READ-LOCK START
|
||||
|
@ -476,7 +477,7 @@ namespace triagens {
|
|||
int readCollectionDocuments (TRI_primary_collection_t* const primary,
|
||||
vector<string>& ids) {
|
||||
TRI_doc_operation_context_t context;
|
||||
TRI_InitReadContextPrimaryCollection(&context, primary);
|
||||
TRI_InitContextPrimaryCollection(&context, primary);
|
||||
|
||||
// READ-LOCK START
|
||||
this->lockExplicit(primary, TRI_TRANSACTION_READ);
|
||||
|
@ -513,7 +514,7 @@ namespace triagens {
|
|||
TRI_voc_size_t limit,
|
||||
uint32_t* total) {
|
||||
TRI_doc_operation_context_t context;
|
||||
TRI_InitReadContextPrimaryCollection(&context, primary);
|
||||
TRI_InitContextPrimaryCollection(&context, primary);
|
||||
|
||||
if (limit == 0) {
|
||||
// nothing to do
|
||||
|
@ -646,7 +647,7 @@ namespace triagens {
|
|||
const bool lock) {
|
||||
|
||||
TRI_doc_operation_context_t context;
|
||||
TRI_InitContextPrimaryCollection(&context, primary, TRI_DOC_UPDATE_LAST_WRITE, forceSync);
|
||||
TRI_InitContextPrimaryCollection(&context, primary);
|
||||
|
||||
// TODO: set transaction lock here
|
||||
return primary->insert(&context, key, mptr, markerType, shaped, data, lock, forceSync);
|
||||
|
@ -693,12 +694,13 @@ namespace triagens {
|
|||
const bool lock) {
|
||||
|
||||
TRI_doc_operation_context_t context;
|
||||
TRI_InitContextPrimaryCollection(&context, primary, policy, forceSync);
|
||||
context._expectedRid = expectedRevision;
|
||||
context._previousRid = actualRevision;
|
||||
TRI_InitContextPrimaryCollection(&context, primary);
|
||||
|
||||
TRI_doc_update_policy_t updatePolicy;
|
||||
TRI_InitUpdatePolicy(&updatePolicy, policy, expectedRevision, actualRevision);
|
||||
|
||||
// TODO: set transaction lock here
|
||||
int res = primary->update(&context, (TRI_voc_key_t) key.c_str(), mptr, shaped, lock, forceSync);
|
||||
int res = primary->update(&context, (TRI_voc_key_t) key.c_str(), mptr, shaped, &updatePolicy, lock, forceSync);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -714,15 +716,16 @@ namespace triagens {
|
|||
TRI_voc_rid_t* actualRevision,
|
||||
const bool forceSync) {
|
||||
TRI_doc_operation_context_t context;
|
||||
TRI_InitContextPrimaryCollection(&context, primary, policy, forceSync);
|
||||
context._expectedRid = expectedRevision;
|
||||
context._previousRid = actualRevision;
|
||||
TRI_InitContextPrimaryCollection(&context, primary);
|
||||
|
||||
TRI_doc_update_policy_t updatePolicy;
|
||||
TRI_InitUpdatePolicy(&updatePolicy, policy, expectedRevision, actualRevision);
|
||||
|
||||
// WRITE-LOCK START
|
||||
this->lockExplicit(primary, TRI_TRANSACTION_WRITE);
|
||||
// TODO: fix locks
|
||||
|
||||
int res = primary->destroy(&context, (TRI_voc_key_t) key.c_str(), false, forceSync);
|
||||
int res = primary->destroy(&context, (TRI_voc_key_t) key.c_str(), &updatePolicy, false, forceSync);
|
||||
|
||||
this->unlockExplicit(primary, TRI_TRANSACTION_WRITE);
|
||||
// WRITE-LOCK END
|
||||
|
@ -745,7 +748,11 @@ namespace triagens {
|
|||
}
|
||||
|
||||
TRI_doc_operation_context_t context;
|
||||
TRI_InitContextPrimaryCollection(&context, primary, TRI_DOC_UPDATE_LAST_WRITE, forceSync);
|
||||
TRI_InitContextPrimaryCollection(&context, primary);
|
||||
|
||||
TRI_doc_update_policy_t updatePolicy;
|
||||
TRI_InitUpdatePolicy(&updatePolicy, TRI_DOC_UPDATE_LAST_WRITE, 0, NULL);
|
||||
|
||||
size_t n = ids.size();
|
||||
|
||||
res = TRI_ERROR_NO_ERROR;
|
||||
|
@ -757,7 +764,7 @@ namespace triagens {
|
|||
for (size_t i = 0; i < n; ++i) {
|
||||
const string& id = ids[i];
|
||||
|
||||
res = primary->destroy(&context, (TRI_voc_key_t) id.c_str(), false, forceSync);
|
||||
res = primary->destroy(&context, (TRI_voc_key_t) id.c_str(), &updatePolicy, false, forceSync);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
// halt on first error
|
||||
|
|
|
@ -1829,7 +1829,7 @@ static v8::Handle<v8::Value> JS_ByExampleQuery (v8::Arguments const& argv) {
|
|||
|
||||
TRI_doc_operation_context_t context;
|
||||
|
||||
TRI_InitReadContextPrimaryCollection(&context, primary);
|
||||
TRI_InitContextPrimaryCollection(&context, primary);
|
||||
|
||||
trx.lockRead();
|
||||
|
||||
|
|
|
@ -124,11 +124,9 @@ static int CopyDocument (TRI_document_collection_t* collection,
|
|||
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);
|
||||
journal = SelectCompactor(collection, marker->_size, result);
|
||||
|
||||
if (journal == NULL) {
|
||||
collection->base.base._lastError = TRI_set_errno(TRI_ERROR_ARANGO_NO_JOURNAL);
|
||||
|
@ -138,15 +136,7 @@ static int CopyDocument (TRI_document_collection_t* collection,
|
|||
*fid = journal->_fid;
|
||||
|
||||
// and write marker and blob
|
||||
return TRI_WriteElementDatafile(journal,
|
||||
*result,
|
||||
marker,
|
||||
marker->_size,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
false);
|
||||
return TRI_WriteElementDatafile(journal, *result, marker, marker->_size, false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
#include "BasicsC/strings.h"
|
||||
#include "BasicsC/files.h"
|
||||
|
||||
#include "VocBase/marker.h"
|
||||
|
||||
|
||||
// #define DEBUG_DATAFILE 1
|
||||
|
||||
|
@ -794,23 +796,17 @@ TRI_datafile_t* TRI_CreateDatafile (char const* filename,
|
|||
|
||||
// create the header
|
||||
memset(&header, 0, sizeof(TRI_df_header_marker_t));
|
||||
|
||||
header.base._size = sizeof(TRI_df_header_marker_t);
|
||||
header.base._tick = TRI_NewTickVocBase();
|
||||
header.base._type = TRI_DF_MARKER_HEADER;
|
||||
TRI_InitMarker(&header.base, TRI_DF_MARKER_HEADER, sizeof(TRI_df_header_marker_t), TRI_NewTickVocBase());
|
||||
|
||||
header._version = TRI_DF_VERSION;
|
||||
header._maximalSize = maximalSize;
|
||||
header._fid = TRI_NewTickVocBase();
|
||||
|
||||
// create CRC
|
||||
TRI_FillCrcMarkerDatafile(datafile, &header.base, sizeof(TRI_df_header_marker_t), 0, 0, 0, 0);
|
||||
|
||||
// reserve space and write header to file
|
||||
result = TRI_ReserveElementDatafile(datafile, header.base._size, &position);
|
||||
|
||||
if (result == TRI_ERROR_NO_ERROR) {
|
||||
result = TRI_WriteElementDatafile(datafile, position, &header.base, header.base._size, 0, 0, 0, 0, true);
|
||||
result = TRI_WriteCrcElementDatafile(datafile, position, &header.base, header.base._size, true);
|
||||
}
|
||||
|
||||
if (result != TRI_ERROR_NO_ERROR) {
|
||||
|
@ -1066,8 +1062,6 @@ bool TRI_CheckCrcMarkerDatafile (TRI_df_marker_t const* marker) {
|
|||
void TRI_FillCrcMarkerDatafile (TRI_datafile_t* datafile,
|
||||
TRI_df_marker_t* marker,
|
||||
TRI_voc_size_t markerSize,
|
||||
void const* keyBody,
|
||||
TRI_voc_size_t keyBodySize,
|
||||
void const* body,
|
||||
TRI_voc_size_t bodySize) {
|
||||
marker->_crc = 0;
|
||||
|
@ -1079,10 +1073,6 @@ void TRI_FillCrcMarkerDatafile (TRI_datafile_t* datafile,
|
|||
crc = TRI_InitialCrc32();
|
||||
crc = TRI_BlockCrc32(crc, (char const*) marker, markerSize);
|
||||
|
||||
if (keyBody != NULL && 0 < keyBodySize) {
|
||||
crc = TRI_BlockCrc32(crc, keyBody, keyBodySize);
|
||||
}
|
||||
|
||||
if (body != NULL && 0 < bodySize) {
|
||||
crc = TRI_BlockCrc32(crc, body, bodySize);
|
||||
}
|
||||
|
@ -1093,6 +1083,7 @@ void TRI_FillCrcMarkerDatafile (TRI_datafile_t* datafile,
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief creates a CRC and writes that into the header
|
||||
/// @deprecated this function is deprecated. do not use for new code
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_FillCrcKeyMarkerDatafile (TRI_datafile_t* datafile,
|
||||
|
@ -1167,26 +1158,19 @@ int TRI_ReserveElementDatafile (TRI_datafile_t* datafile,
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief writes a marker and body to the datafile
|
||||
/// @brief writes a marker to the datafile
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_WriteElementDatafile (TRI_datafile_t* datafile,
|
||||
void* position,
|
||||
TRI_df_marker_t const* marker,
|
||||
TRI_voc_size_t markerSize,
|
||||
void const* keyBody,
|
||||
TRI_voc_size_t keyBodySize,
|
||||
void const* body,
|
||||
TRI_voc_size_t bodySize,
|
||||
bool forceSync) {
|
||||
TRI_voc_size_t size;
|
||||
|
||||
size = markerSize + keyBodySize + bodySize;
|
||||
|
||||
if (size != marker->_size) {
|
||||
if (markerSize != marker->_size) {
|
||||
LOG_ERROR("marker size is %lu, but size is %lu",
|
||||
(unsigned long) marker->_size,
|
||||
(unsigned long) size);
|
||||
(unsigned long) markerSize);
|
||||
}
|
||||
|
||||
if (datafile->_state != TRI_DF_STATE_WRITE) {
|
||||
|
@ -1201,18 +1185,11 @@ int TRI_WriteElementDatafile (TRI_datafile_t* datafile,
|
|||
|
||||
memcpy(position, marker, markerSize);
|
||||
|
||||
if (keyBody != NULL && 0 < keyBodySize) {
|
||||
memcpy(((char*) position) + markerSize, keyBody, keyBodySize);
|
||||
}
|
||||
|
||||
if (body != NULL && 0 < bodySize) {
|
||||
memcpy(((char*) position) + markerSize + keyBodySize, body, bodySize);
|
||||
}
|
||||
|
||||
if (forceSync) {
|
||||
bool ok;
|
||||
|
||||
ok = datafile->sync(datafile, position, ((char*) position) + size);
|
||||
ok = datafile->sync(datafile, position, ((char*) position) + markerSize);
|
||||
|
||||
if (! ok) {
|
||||
datafile->_state = TRI_DF_STATE_WRITE_ERROR;
|
||||
|
@ -1229,13 +1206,32 @@ int TRI_WriteElementDatafile (TRI_datafile_t* datafile,
|
|||
return datafile->_lastError;
|
||||
}
|
||||
else {
|
||||
LOG_TRACE("msync succeeded %p, size %lu", position, (unsigned long) size);
|
||||
LOG_TRACE("msync succeeded %p, size %lu", position, (unsigned long) markerSize);
|
||||
}
|
||||
}
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief checksums and writes a marker to the datafile
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_WriteCrcElementDatafile (TRI_datafile_t* datafile,
|
||||
void* position,
|
||||
TRI_df_marker_t* marker,
|
||||
TRI_voc_size_t markerSize,
|
||||
bool forceSync) {
|
||||
if (datafile->isPhysical(datafile)) {
|
||||
TRI_voc_crc_t crc = TRI_InitialCrc32();
|
||||
|
||||
crc = TRI_BlockCrc32(crc, (char const*) marker, markerSize);
|
||||
marker->_crc = TRI_FinalCrc32(crc);
|
||||
}
|
||||
|
||||
return TRI_WriteElementDatafile(datafile, position, marker, markerSize, forceSync);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief iterates over a datafile
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1448,15 +1444,10 @@ int TRI_SealDatafile (TRI_datafile_t* datafile) {
|
|||
return TRI_set_errno(TRI_ERROR_ARANGO_DATAFILE_SEALED);
|
||||
}
|
||||
|
||||
|
||||
// create the footer
|
||||
memset(&footer, 0, sizeof(TRI_df_footer_marker_t));
|
||||
|
||||
footer.base._size = sizeof(TRI_df_footer_marker_t);
|
||||
footer.base._tick = TRI_NewTickVocBase();
|
||||
footer.base._type = TRI_DF_MARKER_FOOTER;
|
||||
|
||||
// create CRC
|
||||
TRI_FillCrcMarkerDatafile(datafile, &footer.base, sizeof(TRI_df_footer_marker_t), 0, 0, 0, 0);
|
||||
TRI_InitMarker(&footer.base, TRI_DF_MARKER_FOOTER, sizeof(TRI_df_footer_marker_t), TRI_NewTickVocBase());
|
||||
|
||||
// reserve space and write footer to file
|
||||
datafile->_footerSize = 0;
|
||||
|
@ -1464,7 +1455,7 @@ int TRI_SealDatafile (TRI_datafile_t* datafile) {
|
|||
res = TRI_ReserveElementDatafile(datafile, footer.base._size, &position);
|
||||
|
||||
if (res == TRI_ERROR_NO_ERROR) {
|
||||
res = TRI_WriteElementDatafile(datafile, position, &footer.base, footer.base._size, 0, 0, 0, 0, true);
|
||||
res = TRI_WriteCrcElementDatafile(datafile, position, &footer.base, footer.base._size, true);
|
||||
}
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
|
|
|
@ -512,18 +512,7 @@ bool TRI_CheckCrcMarkerDatafile (TRI_df_marker_t const* marker);
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief creates a CRC and writes that into the header
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_FillCrcMarkerDatafile (TRI_datafile_t* datafile,
|
||||
TRI_df_marker_t* marker,
|
||||
TRI_voc_size_t markerSize,
|
||||
void const* keyBody,
|
||||
TRI_voc_size_t keyBodySize,
|
||||
void const* body,
|
||||
TRI_voc_size_t bodySize);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief creates a CRC and writes that into the header
|
||||
/// @deprecated this function is deprecated. do not use for new code.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_FillCrcKeyMarkerDatafile (TRI_datafile_t* datafile,
|
||||
|
@ -543,19 +532,25 @@ int TRI_ReserveElementDatafile (TRI_datafile_t* datafile,
|
|||
TRI_df_marker_t** position);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief writes a marker and body to the datafile
|
||||
/// @brief writes a marker to the datafile
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_WriteElementDatafile (TRI_datafile_t* datafile,
|
||||
void* position,
|
||||
TRI_df_marker_t const* marker,
|
||||
TRI_voc_size_t markerSize,
|
||||
void const* keyBody,
|
||||
TRI_voc_size_t keyBodySize,
|
||||
void const* body,
|
||||
TRI_voc_size_t bodySize,
|
||||
bool sync);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief checksums and writes a marker to the datafile
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_WriteCrcElementDatafile (TRI_datafile_t* datafile,
|
||||
void* position,
|
||||
TRI_df_marker_t* marker,
|
||||
TRI_voc_size_t markerSize,
|
||||
bool sync);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief iterates over a datafile
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "VocBase/index.h"
|
||||
#include "VocBase/key-generator.h"
|
||||
#include "VocBase/marker.h"
|
||||
#include "VocBase/update-policy.h"
|
||||
#include "VocBase/voc-shaper.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -144,8 +145,7 @@ static void CollectionRevisionUpdate (TRI_document_collection_t* document,
|
|||
static int CreateDeletionMarker (TRI_doc_deletion_key_marker_t** result,
|
||||
TRI_voc_size_t* totalSize,
|
||||
char* keyBody,
|
||||
TRI_voc_size_t keyBodySize,
|
||||
const bool calcCrc) {
|
||||
TRI_voc_size_t keyBodySize) {
|
||||
TRI_doc_deletion_key_marker_t* marker;
|
||||
|
||||
*result = NULL;
|
||||
|
@ -164,10 +164,6 @@ static int CreateDeletionMarker (TRI_doc_deletion_key_marker_t** result,
|
|||
// copy the key into the marker
|
||||
memcpy(((char*) marker) + marker->_offsetKey, keyBody, keyBodySize + 1);
|
||||
|
||||
if (calcCrc) {
|
||||
TRI_CrcMarker(&marker->base, *totalSize);
|
||||
}
|
||||
|
||||
*result = marker;
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
|
@ -182,8 +178,7 @@ static int CloneDocumentMarker (TRI_df_marker_t const* original,
|
|||
TRI_doc_document_key_marker_t** result,
|
||||
TRI_voc_size_t* totalSize,
|
||||
const TRI_df_marker_type_e markerType,
|
||||
TRI_shaped_json_t const* shaped,
|
||||
const bool calcCrc) {
|
||||
TRI_shaped_json_t const* shaped) {
|
||||
|
||||
TRI_doc_document_key_marker_t* marker;
|
||||
TRI_voc_tick_t tick;
|
||||
|
@ -256,11 +251,6 @@ static int CloneDocumentMarker (TRI_df_marker_t const* original,
|
|||
}
|
||||
#endif
|
||||
|
||||
if (calcCrc) {
|
||||
// calculate crc checksum
|
||||
TRI_CrcMarker(&marker->base, *totalSize);
|
||||
}
|
||||
|
||||
*result = marker;
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
|
@ -277,8 +267,7 @@ static int CreateDocumentMarker (TRI_primary_collection_t* primary,
|
|||
const TRI_df_marker_type_e markerType,
|
||||
TRI_voc_key_t key,
|
||||
TRI_shaped_json_t const* shaped,
|
||||
void const* data,
|
||||
const bool calcCrc) {
|
||||
void const* data) {
|
||||
TRI_doc_document_key_marker_t* marker;
|
||||
TRI_key_generator_t* keyGenerator;
|
||||
char* position;
|
||||
|
@ -382,11 +371,6 @@ static int CreateDocumentMarker (TRI_primary_collection_t* primary,
|
|||
marker->_offsetKey = markerSize;
|
||||
marker->_offsetJson = markerSize + keyBodySize;
|
||||
|
||||
if (calcCrc) {
|
||||
// calculate crc checksum
|
||||
TRI_CrcMarker(&marker->base, *totalSize);
|
||||
}
|
||||
|
||||
*result = marker;
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
|
@ -414,7 +398,6 @@ static int CreateHeader (TRI_document_collection_t* document,
|
|||
|
||||
header->_rid = tick;
|
||||
header->_fid = fid;
|
||||
header->_validFrom = tick; // document creation time
|
||||
header->_validTo = 0; // document deletion time, 0 means "infinitely valid"
|
||||
header->_data = marker;
|
||||
header->_key = ((char*) marker) + marker->_offsetKey;
|
||||
|
@ -548,29 +531,17 @@ static void WaitSync (TRI_document_collection_t* document,
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief writes data to the journal and updates the barriers
|
||||
/// @brief writes data to the journal
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int WriteElement (TRI_document_collection_t* document,
|
||||
TRI_datafile_t* journal,
|
||||
TRI_df_marker_t const* marker,
|
||||
TRI_df_marker_t* marker,
|
||||
TRI_voc_size_t markerSize,
|
||||
void const* keyBody,
|
||||
TRI_voc_size_t keyBodySize,
|
||||
void const* body,
|
||||
TRI_voc_size_t bodySize,
|
||||
TRI_df_marker_t* result) {
|
||||
int res;
|
||||
|
||||
res = TRI_WriteElementDatafile(journal,
|
||||
result,
|
||||
marker,
|
||||
markerSize,
|
||||
keyBody,
|
||||
keyBodySize,
|
||||
body,
|
||||
bodySize,
|
||||
false);
|
||||
res = TRI_WriteCrcElementDatafile(journal, result, marker, markerSize, false);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return res;
|
||||
|
@ -662,7 +633,7 @@ static int InsertDocument (TRI_document_collection_t* document,
|
|||
|
||||
if (res == TRI_ERROR_NO_ERROR) {
|
||||
// now write marker and blob
|
||||
res = WriteElement(document, journal, &marker->base, totalSize, NULL, 0, NULL, 0, result);
|
||||
res = WriteElement(document, journal, &marker->base, totalSize, result);
|
||||
|
||||
if (res == TRI_ERROR_NO_ERROR) {
|
||||
// writing the element into the datafile has succeeded
|
||||
|
@ -731,6 +702,7 @@ static int InsertDocument (TRI_document_collection_t* document,
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int DeleteDocument (TRI_doc_operation_context_t* context,
|
||||
TRI_doc_update_policy_t const* policy,
|
||||
TRI_doc_deletion_key_marker_t* marker,
|
||||
const TRI_voc_size_t totalSize,
|
||||
const bool forceSync) {
|
||||
|
@ -757,7 +729,8 @@ static int DeleteDocument (TRI_doc_operation_context_t* context,
|
|||
// check the revision
|
||||
// .............................................................................
|
||||
|
||||
res = TRI_RevisionCheck(context, header->_rid);
|
||||
res = TRI_CheckUpdatePolicy(policy, header->_rid);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return res;
|
||||
}
|
||||
|
@ -773,7 +746,7 @@ static int DeleteDocument (TRI_doc_operation_context_t* context,
|
|||
TRI_ASSERT_DEBUG(result != NULL);
|
||||
|
||||
// and write marker and blob
|
||||
res = WriteElement(document, journal, &marker->base, totalSize, NULL, 0, NULL, 0, result);
|
||||
res = WriteElement(document, journal, &marker->base, totalSize, result);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
LOG_ERROR("cannot delete element");
|
||||
|
@ -850,7 +823,7 @@ static int DeleteDocument (TRI_doc_operation_context_t* context,
|
|||
// wait for sync
|
||||
// .............................................................................
|
||||
|
||||
if (context->_sync) {
|
||||
if (forceSync) {
|
||||
WaitSync(document, journal, ((char const*) result) + totalSize);
|
||||
}
|
||||
|
||||
|
@ -874,7 +847,6 @@ static void UpdateHeader (TRI_voc_fid_t fid,
|
|||
newHeader->_data = marker;
|
||||
newHeader->_key = ((char*) marker) + marker->_offsetKey;
|
||||
|
||||
newHeader->_validFrom = oldHeader->_validFrom;
|
||||
newHeader->_validTo = oldHeader->_validTo; // TODO: fix for trx
|
||||
}
|
||||
|
||||
|
@ -884,7 +856,7 @@ static void UpdateHeader (TRI_voc_fid_t fid,
|
|||
|
||||
static int UpdateDocument (TRI_document_collection_t* document,
|
||||
TRI_doc_mptr_t* oldHeader,
|
||||
TRI_doc_document_key_marker_t const* marker,
|
||||
TRI_doc_document_key_marker_t* marker,
|
||||
const TRI_voc_size_t totalSize,
|
||||
const bool forceSync,
|
||||
TRI_doc_mptr_t* mptr) {
|
||||
|
@ -972,7 +944,7 @@ static int UpdateDocument (TRI_document_collection_t* document,
|
|||
|
||||
|
||||
if (res == TRI_ERROR_NO_ERROR) {
|
||||
res = WriteElement(document, journal, &marker->base, totalSize, NULL, 0, NULL, 0, result);
|
||||
res = WriteElement(document, journal, &marker->base, totalSize, result);
|
||||
|
||||
if (res == TRI_ERROR_NO_ERROR) {
|
||||
TRI_doc_datafile_info_t* dfi;
|
||||
|
@ -1250,11 +1222,10 @@ static void DebugHeaderDocumentCollection (TRI_document_collection_t* collection
|
|||
|
||||
d = *ptr;
|
||||
|
||||
printf("fid %llu, key %s, rid %llu, validFrom: %llu validTo %llu\n",
|
||||
printf("fid %llu, key %s, rid %llu, validTo %llu\n",
|
||||
(unsigned long long) d->_fid,
|
||||
(char*) d->_key,
|
||||
(unsigned long long) d->_rid,
|
||||
(unsigned long long) d->_validFrom,
|
||||
(unsigned long long) d->_validTo);
|
||||
}
|
||||
}
|
||||
|
@ -1290,8 +1261,7 @@ static int InsertShapedJson (TRI_doc_operation_context_t* context,
|
|||
// first create a new marker in memory
|
||||
// this does not require any locks
|
||||
|
||||
// TODO: make calcCrc flag (last parameter) dynamic, based on the collection properties
|
||||
res = CreateDocumentMarker(primary, &marker, &totalSize, &keyBody, markerType, key, shaped, data, true);
|
||||
res = CreateDocumentMarker(primary, &marker, &totalSize, &keyBody, markerType, key, shaped, data);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return res;
|
||||
|
@ -1327,6 +1297,15 @@ static int InsertShapedJson (TRI_doc_operation_context_t* context,
|
|||
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, marker);
|
||||
|
||||
#ifdef TRI_ENABLE_MAINTAINER_MODE
|
||||
if (res == TRI_ERROR_NO_ERROR) {
|
||||
TRI_ASSERT_DEBUG(mptr->_key != NULL);
|
||||
TRI_ASSERT_DEBUG(mptr->_data != NULL);
|
||||
TRI_ASSERT_DEBUG(mptr->_rid > 0);
|
||||
TRI_ASSERT_DEBUG(mptr->_fid > 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -1354,6 +1333,13 @@ static int ReadShapedJson (TRI_doc_operation_context_t* context,
|
|||
// we found a document, now copy it over
|
||||
*mptr = *((TRI_doc_mptr_t*) header);
|
||||
|
||||
#ifdef TRI_ENABLE_MAINTAINER_MODE
|
||||
TRI_ASSERT_DEBUG(mptr->_key != NULL);
|
||||
TRI_ASSERT_DEBUG(mptr->_data != NULL);
|
||||
TRI_ASSERT_DEBUG(mptr->_rid > 0);
|
||||
TRI_ASSERT_DEBUG(mptr->_fid > 0);
|
||||
#endif
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
|
@ -1365,6 +1351,7 @@ static int UpdateShapedJson (TRI_doc_operation_context_t* context,
|
|||
const TRI_voc_key_t key,
|
||||
TRI_doc_mptr_t* mptr,
|
||||
TRI_shaped_json_t const* shaped,
|
||||
TRI_doc_update_policy_t const* policy,
|
||||
const bool lock,
|
||||
const bool forceSync) {
|
||||
TRI_primary_collection_t* primary;
|
||||
|
@ -1394,7 +1381,7 @@ static int UpdateShapedJson (TRI_doc_operation_context_t* context,
|
|||
|
||||
if (IsVisible(header, context)) {
|
||||
// document found, now check revision
|
||||
res = TRI_RevisionCheck(context, header->_rid);
|
||||
res = TRI_CheckUpdatePolicy(policy, header->_rid);
|
||||
}
|
||||
else {
|
||||
// document not found
|
||||
|
@ -1407,8 +1394,7 @@ static int UpdateShapedJson (TRI_doc_operation_context_t* context,
|
|||
|
||||
original = header->_data;
|
||||
|
||||
// TODO: make calcCrc flag (last parameter) dynamic, based on the collection properties
|
||||
res = CloneDocumentMarker(original, &marker, &totalSize, original->_type, shaped, true);
|
||||
res = CloneDocumentMarker(original, &marker, &totalSize, original->_type, shaped);
|
||||
|
||||
if (res == TRI_ERROR_NO_ERROR) {
|
||||
res = UpdateDocument((TRI_document_collection_t*) primary, header, marker, totalSize, forceSync, mptr);
|
||||
|
@ -1423,6 +1409,15 @@ static int UpdateShapedJson (TRI_doc_operation_context_t* context,
|
|||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, marker);
|
||||
}
|
||||
|
||||
#ifdef TRI_ENABLE_MAINTAINER_MODE
|
||||
if (res == TRI_ERROR_NO_ERROR) {
|
||||
TRI_ASSERT_DEBUG(mptr->_key != NULL);
|
||||
TRI_ASSERT_DEBUG(mptr->_data != NULL);
|
||||
TRI_ASSERT_DEBUG(mptr->_rid > 0);
|
||||
TRI_ASSERT_DEBUG(mptr->_fid > 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -1432,6 +1427,7 @@ static int UpdateShapedJson (TRI_doc_operation_context_t* context,
|
|||
|
||||
static int DeleteShapedJson (TRI_doc_operation_context_t* context,
|
||||
const TRI_voc_key_t key,
|
||||
TRI_doc_update_policy_t const* policy,
|
||||
const bool lock,
|
||||
const bool forceSync) {
|
||||
TRI_primary_collection_t* primary;
|
||||
|
@ -1441,9 +1437,8 @@ static int DeleteShapedJson (TRI_doc_operation_context_t* context,
|
|||
|
||||
TRI_ASSERT_DEBUG(key != NULL);
|
||||
|
||||
// TODO: make calcCrc dynamic
|
||||
marker = NULL;
|
||||
res = CreateDeletionMarker(&marker, &totalSize, key, strlen(key), true);
|
||||
res = CreateDeletionMarker(&marker, &totalSize, key, strlen(key));
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return res;
|
||||
|
@ -1457,7 +1452,7 @@ static int DeleteShapedJson (TRI_doc_operation_context_t* context,
|
|||
primary->beginWrite(primary);
|
||||
}
|
||||
|
||||
res = DeleteDocument(context, marker, totalSize, forceSync);
|
||||
res = DeleteDocument(context, policy, marker, totalSize, forceSync);
|
||||
|
||||
if (lock) {
|
||||
primary->endWrite(primary);
|
||||
|
@ -1540,13 +1535,13 @@ static bool OpenIterator (TRI_df_marker_t const* marker, void* data, TRI_datafil
|
|||
primary = &collection->base;
|
||||
keyGenerator = primary->_keyGenerator;
|
||||
|
||||
CollectionRevisionUpdate(collection, marker);
|
||||
|
||||
// new or updated document
|
||||
if (marker->_type == TRI_DOC_MARKER_KEY_EDGE ||
|
||||
marker->_type == TRI_DOC_MARKER_KEY_DOCUMENT) {
|
||||
TRI_doc_document_key_marker_t const* d = (TRI_doc_document_key_marker_t const*) marker;
|
||||
size_t markerSize;
|
||||
|
||||
CollectionRevisionUpdate(collection, marker);
|
||||
|
||||
if (marker->_type == TRI_DOC_MARKER_KEY_DOCUMENT) {
|
||||
|
||||
|
@ -1747,7 +1742,6 @@ static bool OpenIterator (TRI_df_marker_t const* marker, void* data, TRI_datafil
|
|||
}
|
||||
|
||||
header->_rid = d->_rid;
|
||||
header->_validFrom = marker->_tick;
|
||||
header->_validTo = marker->_tick; // TODO: fix for trx
|
||||
header->_data = marker;
|
||||
header->_key = key;
|
||||
|
@ -1790,7 +1784,6 @@ static bool OpenIterator (TRI_df_marker_t const* marker, void* data, TRI_datafil
|
|||
newHeader = CONST_CAST(found);
|
||||
|
||||
// mark element as deleted
|
||||
newHeader->_validFrom = marker->_tick;
|
||||
newHeader->_validTo = marker->_tick; // TODO: fix for trx
|
||||
newHeader->_data = marker;
|
||||
newHeader->_key = key;
|
||||
|
@ -2680,7 +2673,7 @@ static int FillIndex (TRI_document_collection_t* document, TRI_index_t* idx) {
|
|||
|
||||
primary = &document->base;
|
||||
|
||||
TRI_InitContextPrimaryCollection(&context, primary, TRI_DOC_UPDATE_LAST_WRITE, false);
|
||||
TRI_InitContextPrimaryCollection(&context, primary);
|
||||
|
||||
// update index
|
||||
ptr = primary->_primaryIndex._table;
|
||||
|
@ -2706,7 +2699,9 @@ static int FillIndex (TRI_document_collection_t* document, TRI_index_t* idx) {
|
|||
++inserted;
|
||||
|
||||
if (inserted % 10000 == 0) {
|
||||
LOG_DEBUG("indexed %llu documents of collection %llu", (unsigned long long) inserted, (unsigned long long) primary->base._info._cid);
|
||||
LOG_DEBUG("indexed %llu documents of collection %llu",
|
||||
(unsigned long long) inserted,
|
||||
(unsigned long long) primary->base._info._cid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5168,9 +5163,10 @@ TRI_vector_t TRI_SelectByExample (TRI_doc_operation_context_t* context,
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_DeleteDocumentDocumentCollection (TRI_doc_operation_context_t* context,
|
||||
TRI_doc_update_policy_t const* policy,
|
||||
TRI_doc_mptr_t* doc) {
|
||||
// no extra locking here as the collection is already locked
|
||||
return DeleteShapedJson(context, doc->_key, false, false);
|
||||
return DeleteShapedJson(context, doc->_key, policy, false, false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -629,8 +629,9 @@ TRI_vector_t TRI_SelectByExample (TRI_doc_operation_context_t*,
|
|||
/// @brief deletes a documet given by a master pointer
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_DeleteDocumentDocumentCollection (TRI_doc_operation_context_t* context,
|
||||
TRI_doc_mptr_t* doc);
|
||||
int TRI_DeleteDocumentDocumentCollection (TRI_doc_operation_context_t*,
|
||||
struct TRI_doc_update_policy_s const*,
|
||||
TRI_doc_mptr_t*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
|
|
|
@ -43,32 +43,18 @@
|
|||
void TRI_InitMarker (TRI_df_marker_t* const marker,
|
||||
TRI_df_marker_type_e type,
|
||||
TRI_voc_size_t size,
|
||||
TRI_voc_tick_t id) {
|
||||
TRI_voc_tick_t tick) {
|
||||
TRI_ASSERT_DEBUG(marker != NULL);
|
||||
TRI_ASSERT_DEBUG(type > TRI_MARKER_MIN && type < TRI_MARKER_MAX);
|
||||
TRI_ASSERT_DEBUG(size > 0);
|
||||
TRI_ASSERT_DEBUG(id > 0);
|
||||
TRI_ASSERT_DEBUG(tick > 0);
|
||||
|
||||
marker->_type = type;
|
||||
marker->_size = size;
|
||||
marker->_tick = id;
|
||||
marker->_tick = tick;
|
||||
marker->_crc = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief calculate the CRC value for a marker
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_CrcMarker (TRI_df_marker_t* const marker,
|
||||
size_t length) {
|
||||
TRI_voc_crc_t crc;
|
||||
|
||||
crc = TRI_InitialCrc32();
|
||||
crc = TRI_BlockCrc32(crc, (char const*) marker, length);
|
||||
|
||||
marker->_crc = TRI_FinalCrc32(crc);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -54,13 +54,6 @@ void TRI_InitMarker (TRI_df_marker_t* const,
|
|||
TRI_voc_size_t,
|
||||
TRI_voc_tick_t);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief calculate the CRC value for a marker
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_CrcMarker (TRI_df_marker_t* const,
|
||||
size_t);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -178,16 +178,12 @@ static TRI_datafile_t* CreateJournal (TRI_primary_collection_t* primary, bool co
|
|||
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_InitMarker(&cm.base, TRI_COL_MARKER_HEADER, sizeof(TRI_col_header_marker_t), TRI_NewTickVocBase());
|
||||
cm._cid = collection->_info._cid;
|
||||
cm._type = (TRI_col_type_t) collection->_info._type;
|
||||
|
||||
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);
|
||||
res = TRI_WriteCrcElementDatafile(journal, position, &cm.base, sizeof(cm), true);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
collection->_lastError = journal->_lastError;
|
||||
|
@ -589,64 +585,8 @@ bool TRI_CloseCompactorPrimaryCollection (TRI_primary_collection_t* primary,
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_InitContextPrimaryCollection (TRI_doc_operation_context_t* const context,
|
||||
TRI_primary_collection_t* const primary,
|
||||
TRI_doc_update_policy_e policy,
|
||||
bool forceSync) {
|
||||
TRI_primary_collection_t* const primary) {
|
||||
context->_collection = primary;
|
||||
context->_policy = policy;
|
||||
context->_expectedRid = 0;
|
||||
context->_previousRid = NULL;
|
||||
context->_sync = forceSync || primary->base._info._waitForSync;
|
||||
context->_allowRollback = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initialise a new operation context for reads
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_InitReadContextPrimaryCollection (TRI_doc_operation_context_t* const context,
|
||||
TRI_primary_collection_t* const primary) {
|
||||
context->_collection = primary;
|
||||
context->_policy = TRI_DOC_UPDATE_LAST_WRITE;
|
||||
context->_expectedRid = 0;
|
||||
context->_previousRid = NULL;
|
||||
context->_sync = false;
|
||||
context->_allowRollback = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief compare revision of found document with revision specified in policy
|
||||
/// this will also store the actual revision id found in the database in the
|
||||
/// context variable _previousRid, but only if this is not NULL
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_RevisionCheck (const TRI_doc_operation_context_t* const context,
|
||||
const TRI_voc_rid_t actualRid) {
|
||||
|
||||
// store previous revision
|
||||
if (context->_previousRid != NULL) {
|
||||
*(context->_previousRid) = actualRid;
|
||||
}
|
||||
|
||||
// check policy
|
||||
switch (context->_policy) {
|
||||
case TRI_DOC_UPDATE_ERROR:
|
||||
if (context->_expectedRid != 0 && context->_expectedRid != actualRid) {
|
||||
return TRI_ERROR_ARANGO_CONFLICT;
|
||||
}
|
||||
break;
|
||||
|
||||
case TRI_DOC_UPDATE_CONFLICT:
|
||||
return TRI_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
case TRI_DOC_UPDATE_ILLEGAL:
|
||||
return TRI_ERROR_INTERNAL;
|
||||
|
||||
case TRI_DOC_UPDATE_LAST_WRITE:
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
#include "BasicsC/json.h"
|
||||
#include "ShapedJson/json-shaper.h"
|
||||
#include "VocBase/barrier.h"
|
||||
#include "VocBase/marker.h"
|
||||
#include "VocBase/update-policy.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -45,9 +47,9 @@ extern "C" {
|
|||
struct TRI_cap_constraint_s;
|
||||
struct TRI_doc_deletion_key_marker_s;
|
||||
struct TRI_doc_document_key_marker_s;
|
||||
struct TRI_doc_update_policy_s;
|
||||
struct TRI_key_generator_s;
|
||||
struct TRI_primary_collection_s;
|
||||
struct TRI_transaction_s;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public macros
|
||||
|
@ -99,34 +101,14 @@ struct TRI_transaction_s;
|
|||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief update and delete policy
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef enum {
|
||||
TRI_DOC_UPDATE_ERROR,
|
||||
TRI_DOC_UPDATE_LAST_WRITE,
|
||||
TRI_DOC_UPDATE_CONFLICT,
|
||||
TRI_DOC_UPDATE_ILLEGAL
|
||||
}
|
||||
TRI_doc_update_policy_e;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief typedef for arbitrary collection operation parameters
|
||||
/// the context controls behavior such as revision check, locking/unlocking
|
||||
///
|
||||
/// the context struct needs to be passed as a parameter for CRUD operations
|
||||
/// this makes function signatures a lot easier
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct TRI_doc_operation_context_s {
|
||||
struct TRI_primary_collection_s* _collection; // collection to be used
|
||||
struct TRI_transaction_s* _transaction; // transaction context
|
||||
TRI_voc_rid_t _expectedRid; // the expected revision id of a document. only used if set and for update/delete
|
||||
TRI_voc_rid_t* _previousRid; // a variable that the previous revsion id found in the database will be pushed into. only used if set and for update/delete
|
||||
TRI_doc_update_policy_e _policy; // the update policy
|
||||
bool _sync : 1; // force syncing to disk after successful operation
|
||||
bool _allowRollback : 1; // allow rollback of operation. this is normally true except for contexts created by rollback operations
|
||||
}
|
||||
TRI_doc_operation_context_t;
|
||||
|
||||
|
@ -135,12 +117,11 @@ TRI_doc_operation_context_t;
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct TRI_doc_mptr_s {
|
||||
TRI_voc_rid_t _rid; // this is the revision identifier
|
||||
TRI_voc_fid_t _fid; // this is the datafile identifier
|
||||
TRI_voc_tick_t _validFrom; // this is the creation time
|
||||
TRI_voc_tick_t _validTo; // this is the deletion time (0 if document is not yet deleted)
|
||||
void const* _data; // this is the pointer to the beginning of the raw marker
|
||||
char* _key; // this is the document identifier (string)
|
||||
TRI_voc_rid_t _rid; // this is the revision identifier
|
||||
TRI_voc_fid_t _fid; // this is the datafile identifier
|
||||
TRI_voc_tick_t _validTo; // this is the deletion time (0 if document is not yet deleted)
|
||||
void const* _data; // this is the pointer to the beginning of the raw marker
|
||||
char* _key; // this is the document identifier (string)
|
||||
}
|
||||
TRI_doc_mptr_t;
|
||||
|
||||
|
@ -280,11 +261,6 @@ TRI_doc_collection_info_t;
|
|||
/// valid revision of the document. If the delete was aborted, than @FA{current}
|
||||
/// contains the revision of the still alive document.
|
||||
///
|
||||
/// @FUN{int destroyLock (TRI_primary_collection_t*, TRI_voc_key_t, TRI_voc_rid_t @FA{rid}, TRI_voc_rid_t* @FA{current}, TRI_doc_update_policy_e)}
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// As before, but the function will acquire and release the write lock.
|
||||
///
|
||||
/// @FUN{TRI_doc_collection_info_t* figures (TRI_primary_collection_t*)}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
|
@ -317,15 +293,12 @@ typedef struct TRI_primary_collection_s {
|
|||
int (*beginWrite) (struct TRI_primary_collection_s*);
|
||||
int (*endWrite) (struct TRI_primary_collection_s*);
|
||||
|
||||
void (*createHeader) (struct TRI_primary_collection_s*, TRI_datafile_t*, TRI_df_marker_t const*, size_t, TRI_doc_mptr_t*, void const* data);
|
||||
void (*updateHeader) (struct TRI_primary_collection_s*, TRI_datafile_t*, TRI_df_marker_t const*, size_t, TRI_doc_mptr_t const*, TRI_doc_mptr_t*);
|
||||
|
||||
int (*insert) (struct TRI_doc_operation_context_s*, const TRI_voc_key_t, TRI_doc_mptr_t*, TRI_df_marker_type_e, TRI_shaped_json_t const*, void const*, const bool, const bool);
|
||||
|
||||
int (*read) (struct TRI_doc_operation_context_s*, const TRI_voc_key_t, TRI_doc_mptr_t*);
|
||||
|
||||
int (*update) (struct TRI_doc_operation_context_s*, const TRI_voc_key_t, TRI_doc_mptr_t*, TRI_shaped_json_t const*, const bool, const bool);
|
||||
int (*destroy) (struct TRI_doc_operation_context_s*, const TRI_voc_key_t, const bool, const bool);
|
||||
int (*update) (struct TRI_doc_operation_context_s*, const TRI_voc_key_t, TRI_doc_mptr_t*, TRI_shaped_json_t const*, struct TRI_doc_update_policy_s const*, const bool, const bool);
|
||||
int (*destroy) (struct TRI_doc_operation_context_s*, const TRI_voc_key_t, struct TRI_doc_update_policy_s const*, const bool, const bool);
|
||||
|
||||
TRI_doc_collection_info_t* (*figures) (struct TRI_primary_collection_s* collection);
|
||||
TRI_voc_size_t (*size) (struct TRI_primary_collection_s* collection);
|
||||
|
@ -442,7 +415,7 @@ int TRI_InitPrimaryCollection (TRI_primary_collection_t*, TRI_shaper_t*);
|
|||
/// @brief destroys a primary collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_DestroyPrimaryCollection (TRI_primary_collection_t* collection);
|
||||
void TRI_DestroyPrimaryCollection (TRI_primary_collection_t*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
|
@ -461,59 +434,41 @@ void TRI_DestroyPrimaryCollection (TRI_primary_collection_t* collection);
|
|||
/// @brief finds a datafile description
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_doc_datafile_info_t* TRI_FindDatafileInfoPrimaryCollection (TRI_primary_collection_t* collection,
|
||||
TRI_voc_fid_t fid);
|
||||
TRI_doc_datafile_info_t* TRI_FindDatafileInfoPrimaryCollection (TRI_primary_collection_t*,
|
||||
TRI_voc_fid_t);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief creates a new journal
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_datafile_t* TRI_CreateJournalPrimaryCollection (TRI_primary_collection_t* collection);
|
||||
TRI_datafile_t* TRI_CreateJournalPrimaryCollection (TRI_primary_collection_t*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief closes an existing journal
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_CloseJournalPrimaryCollection (TRI_primary_collection_t* collection,
|
||||
size_t position);
|
||||
bool TRI_CloseJournalPrimaryCollection (TRI_primary_collection_t*,
|
||||
size_t);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief creates a new compactor file
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_datafile_t* TRI_CreateCompactorPrimaryCollection (TRI_primary_collection_t* collection);
|
||||
TRI_datafile_t* TRI_CreateCompactorPrimaryCollection (TRI_primary_collection_t*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief closes an existing compactor file
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_CloseCompactorPrimaryCollection (TRI_primary_collection_t* collection,
|
||||
size_t position);
|
||||
bool TRI_CloseCompactorPrimaryCollection (TRI_primary_collection_t*,
|
||||
size_t);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initialise a new operation context
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_InitContextPrimaryCollection (TRI_doc_operation_context_t* const,
|
||||
TRI_primary_collection_t* const,
|
||||
TRI_doc_update_policy_e,
|
||||
bool);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initialise a new operation context for reads
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_InitReadContextPrimaryCollection (TRI_doc_operation_context_t* const,
|
||||
TRI_primary_collection_t* const);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief compare revision of found document with revision specified in policy
|
||||
/// this will also store the actual revision id found in the database in the
|
||||
/// context variable _previousRid, but only if this is not NULL
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_RevisionCheck (const TRI_doc_operation_context_t*,
|
||||
const TRI_voc_rid_t);
|
||||
TRI_primary_collection_t* const);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
#include "BasicsC/logging.h"
|
||||
#include "BasicsC/strings.h"
|
||||
|
||||
#include "VocBase/marker.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -51,8 +53,11 @@ static bool CreateJournal (TRI_shape_collection_t* collection) {
|
|||
TRI_df_marker_t* position;
|
||||
char* filename;
|
||||
int res;
|
||||
bool isVolatile;
|
||||
|
||||
if (collection->base._info._isVolatile) {
|
||||
isVolatile = collection->base._info._isVolatile;
|
||||
|
||||
if (isVolatile) {
|
||||
// in memory collection
|
||||
filename = NULL;
|
||||
}
|
||||
|
@ -111,12 +116,13 @@ static bool CreateJournal (TRI_shape_collection_t* collection) {
|
|||
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());
|
||||
TRI_FreeDatafile(journal);
|
||||
TRI_FreeString(TRI_CORE_MEM_ZONE, filename);
|
||||
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
LOG_TRACE("renamed journal to '%s'", filename);
|
||||
}
|
||||
LOG_TRACE("renamed journal to '%s'", filename);
|
||||
|
||||
TRI_FreeString(TRI_CORE_MEM_ZONE, filename);
|
||||
}
|
||||
|
@ -135,19 +141,14 @@ static bool CreateJournal (TRI_shape_collection_t* collection) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// create a header
|
||||
memset(&cm, 0, sizeof(cm));
|
||||
// create the header marker
|
||||
TRI_InitMarker(&cm.base, TRI_COL_MARKER_HEADER, sizeof(TRI_col_header_marker_t), TRI_NewTickVocBase());
|
||||
|
||||
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);
|
||||
cm._cid = collection->base._info._cid;
|
||||
cm._type = TRI_COL_TYPE_SHAPE;
|
||||
|
||||
// on journal creation, always use waitForSync = true
|
||||
res = TRI_WriteElementDatafile(journal, position, &cm.base, sizeof(cm), 0, 0, 0, 0, true);
|
||||
res = TRI_WriteCrcElementDatafile(journal, position, &cm.base, sizeof(cm), true);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
LOG_ERROR("cannot create document header in journal '%s': %s",
|
||||
|
@ -159,8 +160,8 @@ static bool CreateJournal (TRI_shape_collection_t* collection) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// that's it
|
||||
TRI_PushBackVectorPointer(&collection->base._journals, journal);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -296,9 +297,7 @@ 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) {
|
||||
TRI_voc_size_t markerSize) {
|
||||
int res;
|
||||
bool waitForSync;
|
||||
|
||||
|
@ -315,7 +314,7 @@ static int WriteElement (TRI_shape_collection_t* collection,
|
|||
waitForSync = false;
|
||||
}
|
||||
|
||||
res = TRI_WriteElementDatafile(journal, position, marker, markerSize, 0, 0, body, bodySize, waitForSync);
|
||||
res = TRI_WriteCrcElementDatafile(journal, position, marker, markerSize, waitForSync);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
collection->base._state = TRI_COL_STATE_WRITE_ERROR;
|
||||
|
@ -413,15 +412,10 @@ void TRI_FreeShapeCollection (TRI_shape_collection_t* collection) {
|
|||
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);
|
||||
|
||||
|
@ -437,7 +431,7 @@ int TRI_WriteShapeCollection (TRI_shape_collection_t* collection,
|
|||
}
|
||||
|
||||
// find and select a journal
|
||||
journal = SelectJournal(collection, markerSize + bodySize, result);
|
||||
journal = SelectJournal(collection, markerSize, result);
|
||||
|
||||
if (journal == NULL) {
|
||||
TRI_UnlockMutex(&collection->_lock);
|
||||
|
@ -445,11 +439,8 @@ int TRI_WriteShapeCollection (TRI_shape_collection_t* collection,
|
|||
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);
|
||||
// write marker and shape
|
||||
res = WriteElement(collection, journal, *result, marker, markerSize);
|
||||
|
||||
// release lock on collection
|
||||
TRI_UnlockMutex(&collection->_lock);
|
||||
|
|
|
@ -121,8 +121,6 @@ void TRI_FreeShapeCollection (TRI_shape_collection_t* collection);
|
|||
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);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief document update / delete policies
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2004-2013 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "update-policy.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup VocBase
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initialise a policy object
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_InitUpdatePolicy (TRI_doc_update_policy_t* const policy,
|
||||
TRI_doc_update_policy_e type,
|
||||
TRI_voc_rid_t expectedRid,
|
||||
TRI_voc_rid_t* previousRid) {
|
||||
policy->_policy = type;
|
||||
policy->_expectedRid = expectedRid;
|
||||
policy->_previousRid = previousRid;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief compare revision of found document with revision specified in policy
|
||||
/// this will also store the actual revision id found in the database in the
|
||||
/// context variable _previousRid, but only if this is not NULL
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_CheckUpdatePolicy (const TRI_doc_update_policy_t* const policy,
|
||||
const TRI_voc_rid_t actualRid) {
|
||||
|
||||
if (policy == NULL) {
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
// store previous revision
|
||||
if (policy->_previousRid != NULL) {
|
||||
*(policy->_previousRid) = actualRid;
|
||||
}
|
||||
|
||||
// check policy
|
||||
switch (policy->_policy) {
|
||||
case TRI_DOC_UPDATE_ERROR:
|
||||
if (policy->_expectedRid != 0 && policy->_expectedRid != actualRid) {
|
||||
return TRI_ERROR_ARANGO_CONFLICT;
|
||||
}
|
||||
break;
|
||||
|
||||
case TRI_DOC_UPDATE_CONFLICT:
|
||||
return TRI_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
case TRI_DOC_UPDATE_ILLEGAL:
|
||||
return TRI_ERROR_INTERNAL;
|
||||
|
||||
case TRI_DOC_UPDATE_LAST_WRITE:
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
|
@ -0,0 +1,115 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief document update / delete policies
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2004-2013 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef TRIAGENS_VOC_BASE_DOCUMENT_POLICY_H
|
||||
#define TRIAGENS_VOC_BASE_DOCUMENT_POLICY_H 1
|
||||
|
||||
#include "BasicsC/common.h"
|
||||
#include "VocBase/vocbase.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public types
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup VocBase
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief update and delete policy
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef enum {
|
||||
TRI_DOC_UPDATE_ERROR,
|
||||
TRI_DOC_UPDATE_LAST_WRITE,
|
||||
TRI_DOC_UPDATE_CONFLICT,
|
||||
TRI_DOC_UPDATE_ILLEGAL
|
||||
}
|
||||
TRI_doc_update_policy_e;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief policy container
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct TRI_doc_update_policy_s {
|
||||
TRI_voc_rid_t _expectedRid; // the expected revision id of a document. only used if set and for update/delete
|
||||
TRI_voc_rid_t* _previousRid; // a variable that the previous revsion id found in the database will be pushed into. only used if set and for update/delete
|
||||
TRI_doc_update_policy_e _policy; // the update policy
|
||||
}
|
||||
TRI_doc_update_policy_t;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup VocBase
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initialise a policy object
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_InitUpdatePolicy (TRI_doc_update_policy_t* const,
|
||||
TRI_doc_update_policy_e,
|
||||
TRI_voc_rid_t,
|
||||
TRI_voc_rid_t*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief compare revision of found document with revision specified in policy
|
||||
/// this will also store the actual revision id found in the database in the
|
||||
/// context variable _previousRid, but only if this is not NULL
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_CheckUpdatePolicy (const TRI_doc_update_policy_t* const,
|
||||
const TRI_voc_rid_t);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
|
@ -362,12 +362,14 @@ static void fullSetAttributeWeight (voc_shaper_t* shaper) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static TRI_shape_aid_t FindAttributeName (TRI_shaper_t* shaper, char const* name) {
|
||||
TRI_df_attribute_marker_t marker;
|
||||
TRI_df_attribute_marker_t* marker;
|
||||
TRI_df_marker_t* result;
|
||||
TRI_df_attribute_marker_t* markerResult;
|
||||
int res;
|
||||
size_t n;
|
||||
voc_shaper_t* s;
|
||||
TRI_shape_aid_t aid;
|
||||
TRI_voc_size_t totalSize;
|
||||
void const* p;
|
||||
void* f;
|
||||
int64_t searchResult;
|
||||
|
@ -381,8 +383,25 @@ static TRI_shape_aid_t FindAttributeName (TRI_shaper_t* shaper, char const* name
|
|||
return ((TRI_df_attribute_marker_t const*) p)->_aid;
|
||||
}
|
||||
|
||||
|
||||
// create a new attribute name
|
||||
n = strlen(name) + 1;
|
||||
|
||||
totalSize = sizeof(TRI_df_attribute_marker_t) + n;
|
||||
marker = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, totalSize * sizeof(char), false);
|
||||
|
||||
if (marker == NULL) {
|
||||
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// init attribute marker
|
||||
TRI_InitMarker(&marker->base, TRI_DF_MARKER_ATTRIBUTE, totalSize, TRI_NewTickVocBase());
|
||||
|
||||
// copy attribute name into marker
|
||||
memcpy(((char*) marker) + sizeof(TRI_df_attribute_marker_t), name, n);
|
||||
marker->_size = n;
|
||||
|
||||
// lock the index and check that the element is still missing
|
||||
TRI_LockMutex(&s->_attributeLock);
|
||||
|
@ -392,20 +411,19 @@ static TRI_shape_aid_t FindAttributeName (TRI_shaper_t* shaper, char const* name
|
|||
// if the element appeared, return the aid
|
||||
if (p != NULL) {
|
||||
TRI_UnlockMutex(&s->_attributeLock);
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, marker);
|
||||
|
||||
return ((TRI_df_attribute_marker_t const*) p)->_aid;
|
||||
}
|
||||
|
||||
// create new attribute identifier
|
||||
memset(&marker, 0, sizeof(TRI_df_attribute_marker_t));
|
||||
|
||||
marker.base._type = TRI_DF_MARKER_ATTRIBUTE;
|
||||
marker.base._size = sizeof(TRI_df_attribute_marker_t) + n;
|
||||
|
||||
marker._aid = s->_nextAid++;
|
||||
marker._size = n;
|
||||
// get next attribute id and write into marker
|
||||
aid = s->_nextAid++;
|
||||
marker->_aid = aid;
|
||||
|
||||
// write into the shape collection
|
||||
res = TRI_WriteShapeCollection(s->_collection, &marker.base, sizeof(TRI_df_attribute_marker_t), name, n, &result);
|
||||
res = TRI_WriteShapeCollection(s->_collection, &marker->base, totalSize, &result);
|
||||
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, marker);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
TRI_UnlockMutex(&s->_attributeLock);
|
||||
|
@ -416,7 +434,7 @@ static TRI_shape_aid_t FindAttributeName (TRI_shaper_t* shaper, char const* name
|
|||
f = TRI_InsertKeyAssociativeSynced(&s->_attributeNames, name, result);
|
||||
assert(f == NULL);
|
||||
|
||||
f = TRI_InsertKeyAssociativeSynced(&s->_attributeIds, &marker._aid, result);
|
||||
f = TRI_InsertKeyAssociativeSynced(&s->_attributeIds, &aid, result);
|
||||
assert(f == NULL);
|
||||
|
||||
// ...........................................................................
|
||||
|
@ -466,7 +484,7 @@ static TRI_shape_aid_t FindAttributeName (TRI_shaper_t* shaper, char const* name
|
|||
|
||||
TRI_UnlockMutex(&s->_attributeLock);
|
||||
|
||||
return marker._aid;
|
||||
return aid;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -587,14 +605,14 @@ static bool EqualElementShape (TRI_associative_synced_t* array, void const* left
|
|||
|
||||
static TRI_shape_t const* FindShape (TRI_shaper_t* shaper, TRI_shape_t* shape) {
|
||||
TRI_df_marker_t* result;
|
||||
TRI_df_shape_marker_t marker;
|
||||
TRI_df_shape_marker_t* marker;
|
||||
TRI_voc_size_t totalSize;
|
||||
TRI_shape_t const* found;
|
||||
TRI_shape_t* l;
|
||||
int res;
|
||||
voc_shaper_t* s;
|
||||
void* f;
|
||||
|
||||
|
||||
s = (voc_shaper_t*) shaper;
|
||||
found = TRI_LookupByElementAssociativeSynced(&s->_shapeDictionary, shape);
|
||||
|
||||
|
@ -604,6 +622,23 @@ static TRI_shape_t const* FindShape (TRI_shaper_t* shaper, TRI_shape_t* shape) {
|
|||
return found;
|
||||
}
|
||||
|
||||
// initialise a new shape marker
|
||||
totalSize = sizeof(TRI_df_shape_marker_t) + shape->_size;
|
||||
marker = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, totalSize * sizeof(char), false);
|
||||
|
||||
if (marker == NULL) {
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, shape);
|
||||
|
||||
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TRI_InitMarker(&marker->base, TRI_DF_MARKER_SHAPE, totalSize, TRI_NewTickVocBase());
|
||||
|
||||
// copy shape into the marker
|
||||
memcpy(((char*) marker) + sizeof(TRI_df_shape_marker_t), shape, shape->_size);
|
||||
|
||||
|
||||
// lock the index and check the element is still missing
|
||||
TRI_LockMutex(&s->_shapeLock);
|
||||
|
||||
|
@ -611,29 +646,26 @@ static TRI_shape_t const* FindShape (TRI_shaper_t* shaper, TRI_shape_t* shape) {
|
|||
|
||||
if (found != 0) {
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, shape);
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, marker);
|
||||
|
||||
TRI_UnlockMutex(&s->_shapeLock);
|
||||
return found;
|
||||
}
|
||||
|
||||
// create a new shape marker
|
||||
memset(&marker, 0, sizeof(TRI_df_shape_marker_t));
|
||||
|
||||
marker.base._type = TRI_DF_MARKER_SHAPE;
|
||||
marker.base._size = sizeof(TRI_df_shape_marker_t) + shape->_size;
|
||||
|
||||
shape->_sid = s->_nextSid++;
|
||||
// get next shape number and write into marker
|
||||
((TRI_shape_t*) (((char*) marker) + sizeof(TRI_df_shape_marker_t)))->_sid = s->_nextSid++;
|
||||
|
||||
// write into the shape collection
|
||||
res = TRI_WriteShapeCollection(s->_collection, &marker.base, sizeof(TRI_df_shape_marker_t), shape, shape->_size, &result);
|
||||
res = TRI_WriteShapeCollection(s->_collection, &marker->base, totalSize, &result);
|
||||
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, shape);
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, marker);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
TRI_UnlockMutex(&s->_shapeLock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, shape);
|
||||
|
||||
// enter into the dictionaries
|
||||
l = (TRI_shape_t*) (((char*) result) + sizeof(TRI_df_shape_marker_t));
|
||||
|
||||
|
@ -655,8 +687,12 @@ static int attributeWeightCompareFunction (const void* leftItem, const void* rig
|
|||
const weighted_attribute_t* l = (const weighted_attribute_t*)(leftItem);
|
||||
const weighted_attribute_t* r = (const weighted_attribute_t*)(rightItem);
|
||||
|
||||
if (l->_weight < r->_weight) { return -1; }
|
||||
if (l->_weight > r->_weight) { return 1; }
|
||||
if (l->_weight < r->_weight) {
|
||||
return -1;
|
||||
}
|
||||
if (l->_weight > r->_weight) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
#save-new-collection, #save-modified-collection {
|
||||
margin-right: 2px !important;
|
||||
}
|
||||
|
||||
#delete-modified-collection {
|
||||
margin-left: 1px !important;
|
||||
}
|
||||
|
|
@ -1,4 +1,10 @@
|
|||
.arango-nav li {
|
||||
margin-left: 1px !important;
|
||||
}
|
||||
|
||||
#transparentHeader .btn-group {
|
||||
margin-top: 6px !important;
|
||||
}
|
||||
|
||||
#newCollection {
|
||||
margin-left: 22px;
|
||||
|
|
|
@ -28,6 +28,13 @@ table.dataTable td {
|
|||
padding-bottom: 15px;
|
||||
}
|
||||
|
||||
#totalDocuments{
|
||||
float: left;
|
||||
color: black;
|
||||
padding-left: 20px;
|
||||
margin-top: -65px !important;
|
||||
}
|
||||
|
||||
#documentsStatus {
|
||||
padding-top: 10px;
|
||||
float:left;
|
||||
|
|
|
@ -200,3 +200,10 @@ table .sorting {
|
|||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.disabledHover {
|
||||
cursor: default !important;
|
||||
}
|
||||
|
||||
.disabledHover:hover {
|
||||
background-color: #8F8D8C !important;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
.arango-nav .active {
|
||||
border-left: 1px solid black;
|
||||
border-right: 1px solid black;
|
||||
.arango-nav {
|
||||
}
|
||||
|
||||
.dropdown-menu li > a:hover, .dropdown-menu li > a:focus, .dropdown-submenu:hover > a {
|
||||
|
|
|
@ -125,3 +125,7 @@
|
|||
.jqconsole-blurred .jqconsole-prompt, .jqconsole-blurred .jqconsole-old-prompt{
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
#queryOutput .ace_gutter-cell {
|
||||
background-color: #F0F0F0 !important;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,8 @@ arangoHelper = {
|
|||
arangoNotification: function (message) {
|
||||
$.gritter.add({
|
||||
title: "Notification:",
|
||||
text: message
|
||||
text: message,
|
||||
time: 800
|
||||
});
|
||||
},
|
||||
arangoError: function (message) {
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -3,7 +3,7 @@
|
|||
|
||||
<!-- /btn-group -->
|
||||
<div class="btn-group pull-right">
|
||||
<button class="btn btn-inverse btn-small">Filter:</button>
|
||||
<button class="btn btn-inverse btn-small disabledHover">Filter:</button>
|
||||
<button data-toggle="dropdown" class="btn btn-inverse btn-small dropdown-toggle"><span class="caret"></span></button>
|
||||
|
||||
<ul class="dropdown-menu">
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<table cellpadding="0" cellspacing="0" border="0" class="display" id="documentTableID" width="100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Key</th>
|
||||
<th>Attribute</th>
|
||||
<th> </th>
|
||||
<th>Value</th>
|
||||
<th>type</th>
|
||||
|
|
Binary file not shown.
|
@ -42,7 +42,6 @@ var documentView = Backbone.View.extend({
|
|||
|
||||
listenKey: function(e) {
|
||||
if (e.keyCode === 13) {
|
||||
console.log('enter');
|
||||
$('.btn-success').click();
|
||||
}
|
||||
},
|
||||
|
@ -339,7 +338,8 @@ var documentView = Backbone.View.extend({
|
|||
cancelcssclass: 'btn btn-danger pull-right',
|
||||
cancel: '<button class="cancelButton btn btn-danger pull-right">Cancel</button">',
|
||||
submit: 'Save',
|
||||
onblur: 'cancel',
|
||||
onblur: 'ignore',
|
||||
//onblur: 'cancel',
|
||||
autogrow: {lineHeight: 16, minHeight: 30}
|
||||
//style: 'display: inline',
|
||||
});
|
||||
|
|
|
@ -191,6 +191,7 @@ var documentsView = Backbone.View.extend({
|
|||
"aaSorting": [[ 1, "asc" ]],
|
||||
"bFilter": false,
|
||||
"bPaginate":false,
|
||||
"bRetrieve": true,
|
||||
"bSortable": false,
|
||||
"bSort": false,
|
||||
"bLengthChange": false,
|
||||
|
@ -198,9 +199,9 @@ var documentsView = Backbone.View.extend({
|
|||
"iDisplayLength": -1,
|
||||
"bJQueryUI": false,
|
||||
"aoColumns": [
|
||||
{ "sClass":"read_only leftCell docleftico", "bSortable": false, "sWidth":"30px"},
|
||||
{ "sClass":"read_only arangoTooltip","bSortable": false},
|
||||
{ "bSortable": false, "sClass": "cuttedContent rightCell"}
|
||||
{ "sClass":"", "bSortable": false, "sWidth":"30px"},
|
||||
{ "sClass":"","bSortable": false},
|
||||
{ "bSortable": false, "sClass": ""}
|
||||
],
|
||||
"oLanguage": { "sEmptyTable": "No documents"}
|
||||
});
|
||||
|
@ -210,7 +211,18 @@ var documentsView = Backbone.View.extend({
|
|||
},
|
||||
drawTable: function() {
|
||||
var self = this;
|
||||
var toCheck = true;
|
||||
$.each(window.arangoDocumentsStore.models, function(key, value) {
|
||||
|
||||
if (toCheck === true) {
|
||||
$(self.table).dataTable().fnAddData([
|
||||
'',
|
||||
'<a id="plusIconDoc" style="padding-left: 30px">Add document</a>',
|
||||
'<img src="/_admin/html/img/plus_icon.png" id="documentAddBtn"></img>'
|
||||
]);
|
||||
toCheck = false;
|
||||
}
|
||||
|
||||
$(self.table).dataTable().fnAddData([
|
||||
//value.attributes.id,
|
||||
value.attributes.key,
|
||||
|
@ -218,13 +230,7 @@ var documentsView = Backbone.View.extend({
|
|||
'<pre class=prettify title="'+self.escaped(JSON.stringify(value.attributes.content)) +'">' + self.cutByResolution(JSON.stringify(value.attributes.content)) + '</pre>',
|
||||
'<button class="enabled" id="deleteDoc"><img src="/_admin/html/img/icon_delete.png" width="16" height="16"></button>'
|
||||
]);
|
||||
console.log(value.attributes.key);
|
||||
});
|
||||
$(self.table).dataTable().fnAddData([
|
||||
'',
|
||||
'<a id="plusIconDoc" style="padding-left: 30px">Add document</a>',
|
||||
'<img src="/_admin/html/img/plus_icon.png" id="documentAddBtn"></img>'
|
||||
]);
|
||||
$(".prettify").snippet("javascript", {style: "nedit", menu: false, startText: false, transparent: true, showNum: false});
|
||||
/* $(".prettify").tooltip({
|
||||
html: true,
|
||||
|
@ -249,6 +255,7 @@ var documentsView = Backbone.View.extend({
|
|||
this.collectionContext = window.arangoCollectionsStore.getPosition(this.colid);
|
||||
|
||||
$(this.el).html(this.template.text);
|
||||
this.initTable();
|
||||
this.breadcrumb();
|
||||
if (this.collectionContext.prev === null) {
|
||||
$('#collectionPrev').parent().addClass('disabledPag');
|
||||
|
@ -277,7 +284,7 @@ var documentsView = Backbone.View.extend({
|
|||
target.pagination(options);
|
||||
$('#documentsToolbarF').prepend('<ul class="prePagi"><li><a id="documents_first"><i class="icon icon-step-backward"></i></a></li></ul>');
|
||||
$('#documentsToolbarF').append('<ul class="lasPagi"><li><a id="documents_last"><i class="icon icon-step-forward"></i></a></li></ul>');
|
||||
//$('#documentsToolbarF2').append('<a>Total: ' + this.documentsCount + ' documents</a>');
|
||||
$('#documentsToolbarFL').append('<a id="totalDocuments">Total: ' + this.documentsCount + ' documents </a>');
|
||||
},
|
||||
breadcrumb: function () {
|
||||
var name = window.location.hash.split("/")[1];
|
||||
|
|
|
@ -153,7 +153,6 @@ var logsView = Backbone.View.extend({
|
|||
self.lastTable();
|
||||
}
|
||||
else {
|
||||
console.log("Number: " + i);
|
||||
self.jumpToTable(i);
|
||||
}
|
||||
options.page = i;
|
||||
|
|
|
@ -56,7 +56,6 @@ var queryView = Backbone.View.extend({
|
|||
var queryContent = localStorage.getItem("queryContent");
|
||||
var queryOutput = localStorage.getItem("queryOutput");
|
||||
editor.setValue(queryContent);
|
||||
console.log(queryOutput);
|
||||
editor2.setValue(queryOutput);
|
||||
}
|
||||
return this;
|
||||
|
|
|
@ -392,18 +392,18 @@ void TRI_UnlockCondition (TRI_condition_t* cond);
|
|||
///
|
||||
/// The position of 'theValue' must be aligned on a 32 bit boundary. The function
|
||||
/// performs the following atomically: compares the value stored in the position
|
||||
/// pointed to by <theValue> with the value of <oldValue>. if the value stored
|
||||
/// in position <theValue> is EQUAL to the value of <oldValue>, then the
|
||||
/// <newValue> is stored in the position pointed to by <theValue> (true is
|
||||
/// pointed to by `theValue` with the value of `oldValue`. if the value stored
|
||||
/// in position `theValue` is EQUAL to the value of `oldValue`, then the
|
||||
/// `newValue` is stored in the position pointed to by `theValue` (true is
|
||||
/// returned), otherwise no operation is performed (false is returned).
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// .............................................................................
|
||||
// The position of 'theValue' must be aligned on a 32 bit boundary. The function
|
||||
// performs the following atomically: compares the value stored in the position
|
||||
// pointed to by <theValue> with the value of <oldValue>. if the value stored
|
||||
// in position <theValue> is EQUAL to the value of <oldValue>, then the
|
||||
// <newValue> is stored in the position pointed to by <theValue> (true is
|
||||
// pointed to by `theValue` with the value of `oldValue`. if the value stored
|
||||
// in position `theValue` is EQUAL to the value of `oldValue`, then the
|
||||
// `newValue` is stored in the position pointed to by `theValue` (true is
|
||||
// returned), otherwise no operation is performed (false is returned).
|
||||
// .............................................................................
|
||||
|
||||
|
@ -435,9 +435,9 @@ bool TRI_CompareAndSwapIntegerUInt64 (volatile uint64_t* theValue, uint64_t oldV
|
|||
/// On a 32bit machine, the position of 'theValue' must be aligned on a 32 bit
|
||||
/// boundary. On a 64bit machine the alignment must be on a 64bit boundary.
|
||||
/// The function performs the following atomically: compares the value stored in
|
||||
/// the position pointed to by <theValue> with the value of <oldValue>. if the
|
||||
/// value stored in position <theValue> is EQUAL to the value of <oldValue>,
|
||||
/// then the <newValue> is stored in the position pointed to by <theValue>
|
||||
/// the position pointed to by `theValue` with the value of `oldValue`. if the
|
||||
/// value stored in position `theValue` is EQUAL to the value of `oldValue`,
|
||||
/// then the `newValue` is stored in the position pointed to by `theValue`
|
||||
/// (true is returned), otherwise no operation is performed (false is returned).
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
Loading…
Reference in New Issue