1
0
Fork 0
This commit is contained in:
Jan Steemann 2014-05-21 18:05:08 +02:00
parent 0f3590315c
commit 0caa570274
8 changed files with 343 additions and 38 deletions

View File

@ -38,6 +38,7 @@
#include "SimpleHttpClient/SimpleHttpResult.h" #include "SimpleHttpClient/SimpleHttpResult.h"
#include "Utils/DocumentHelper.h" #include "Utils/DocumentHelper.h"
#include "VocBase/collection.h" #include "VocBase/collection.h"
#include "VocBase/document-collection.h"
#include "VocBase/edge-collection.h" #include "VocBase/edge-collection.h"
#include "VocBase/primary-collection.h" #include "VocBase/primary-collection.h"
#include "VocBase/server.h" #include "VocBase/server.h"

View File

@ -947,14 +947,14 @@ namespace triagens {
TRI_primary_collection_t* primary = primaryCollection(trxCollection); TRI_primary_collection_t* primary = primaryCollection(trxCollection);
int res = primary->update(trxCollection, int res = primary->updateDocument(trxCollection,
(const TRI_voc_key_t) key.c_str(), (TRI_voc_key_t) key.c_str(),
rid, rid,
mptr, mptr,
shaped, shaped,
&updatePolicy, &updatePolicy,
! isLocked(trxCollection, TRI_TRANSACTION_WRITE), ! isLocked(trxCollection, TRI_TRANSACTION_WRITE),
forceSync); forceSync);
return res; return res;
} }

View File

@ -2450,8 +2450,8 @@ static v8::Handle<v8::Value> SaveEdgeCol (
// the following values are defaults that will be overridden below // the following values are defaults that will be overridden below
edge._fromCid = 0; edge._fromCid = 0;
edge._toCid = 0; edge._toCid = 0;
edge._fromKey = 0; edge._fromKey = nullptr;
edge._toKey = 0; edge._toKey = nullptr;
// extract from // extract from
res = TRI_ParseVertex(resolver, edge._fromCid, edge._fromKey, argv[0], false); res = TRI_ParseVertex(resolver, edge._fromCid, edge._fromKey, argv[0], false);

View File

@ -1883,6 +1883,175 @@ static int ReadShapedJson (TRI_transaction_collection_t* trxCollection,
return TRI_ERROR_NO_ERROR; return TRI_ERROR_NO_ERROR;
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief updates a document in the indexes
////////////////////////////////////////////////////////////////////////////////
static int UpdateIndexes (TRI_transaction_collection_t* trxCollection,
TRI_doc_mptr_t* oldHeader,
TRI_doc_mptr_t* newHeader,
bool forceSync) {
// remove old document from secondary indexes
// (it will stay in the primary index as the key won't change)
TRI_document_collection_t* document = (TRI_document_collection_t*) trxCollection->_collection->_collection;
int res = DeleteSecondaryIndexes(document, oldHeader, false);
if (res != TRI_ERROR_NO_ERROR) {
// re-enter the document in case of failure, ignore errors during rollback
InsertSecondaryIndexes(document, oldHeader, true);
return res;
}
// insert new document into secondary indexes
res = InsertSecondaryIndexes(document, newHeader, false);
if (res != TRI_ERROR_NO_ERROR) {
// rollback
DeleteSecondaryIndexes(document, newHeader, true);
InsertSecondaryIndexes(document, oldHeader, true);
return res;
}
res = AddTransactionOperation(trxCollection,
TRI_VOC_DOCUMENT_OPERATION_UPDATE,
newHeader,
oldHeader,
oldHeader,
newHeader->_data,
newHeader->_rid,
forceSync);
if (res != TRI_ERROR_NO_ERROR) {
RollbackUpdate(document, newHeader, oldHeader, false);
}
return res;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief updates a document in the collection from shaped json
////////////////////////////////////////////////////////////////////////////////
static int UpdateDocumentShapedJson (TRI_transaction_collection_t* trxCollection,
TRI_voc_key_t key,
TRI_voc_rid_t rid,
TRI_doc_mptr_t* mptr,
TRI_shaped_json_t const* shaped,
TRI_doc_update_policy_t const* policy,
bool lock,
bool forceSync) {
if (rid == 0) {
// generate new revision id
rid = static_cast<TRI_voc_rid_t>(TRI_NewTickServer());
}
// initialise the result
assert(mptr != nullptr);
mptr->_key = nullptr;
mptr->_data = nullptr;
TRI_primary_collection_t* primary = trxCollection->_collection->_collection;
triagens::arango::CollectionWriteLocker collectionLocker(primary, lock);
// get the header pointer of the previous revision
assert(key != nullptr);
TRI_doc_mptr_t* oldHeader = static_cast<TRI_doc_mptr_t*>(TRI_LookupByKeyAssociativePointer(&primary->_primaryIndex, key));
int res;
if (IsVisible(oldHeader)) {
// document found, now check revision
res = TRI_CheckUpdatePolicy(policy, oldHeader->_rid);
}
else {
// document not found
res = TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND;
}
if (res != TRI_ERROR_NO_ERROR) {
return res;
}
triagens::basics::JsonLegend legend(primary->_shaper);
res = legend.addShape(shaped->_sid, &shaped->_data);
if (res != TRI_ERROR_NO_ERROR) {
return res;
}
triagens::wal::SlotInfo slotInfo;
TRI_df_marker_t const* original = static_cast<TRI_df_marker_t const*>(oldHeader->_data);
if (original->_type == TRI_WAL_MARKER_DOCUMENT ||
original->_type == TRI_DOC_MARKER_KEY_DOCUMENT) {
triagens::wal::DocumentMarker marker = triagens::wal::DocumentMarker::clone(original,
primary->base._vocbase->_id,
primary->base._info._cid,
rid,
trxCollection->_transaction->_id,
legend,
shaped);
slotInfo = triagens::wal::LogfileManager::instance()->writeMarker(marker, forceSync);
}
else if (original->_type == TRI_WAL_MARKER_EDGE ||
original->_type == TRI_DOC_MARKER_KEY_EDGE) {
triagens::wal::EdgeMarker marker = triagens::wal::EdgeMarker::clone(original,
primary->base._vocbase->_id,
primary->base._info._cid,
rid,
trxCollection->_transaction->_id,
legend,
shaped);
slotInfo = triagens::wal::LogfileManager::instance()->writeMarker(marker, forceSync);
}
else {
// invalid marker type
assert(false);
return TRI_ERROR_INTERNAL;
}
if (slotInfo.errorCode != TRI_ERROR_NO_ERROR) {
// some error occurred
return slotInfo.errorCode;
}
triagens::wal::document_marker_t const* m = static_cast<triagens::wal::document_marker_t const*>(slotInfo.mem);
TRI_doc_mptr_t newHeader;
newHeader._rid = rid;
newHeader._fid = 0; // TODO
newHeader._data = slotInfo.mem;
newHeader._key = static_cast<char*>(const_cast<void*>(slotInfo.mem)) + m->_offsetKey;
res = UpdateIndexes(trxCollection, oldHeader, &newHeader, forceSync);
if (res != TRI_ERROR_NO_ERROR) {
return res;
}
// update the old header in place
oldHeader->_rid = newHeader._rid;
oldHeader->_fid = newHeader._fid;
oldHeader->_data = newHeader._data;
oldHeader->_key = newHeader._key;
// return value
*mptr = newHeader;
assert(mptr->_key != nullptr);
assert(mptr->_data != nullptr);
assert(mptr->_rid > 0);
return res;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief updates a document in the collection from shaped json /// @brief updates a document in the collection from shaped json
@ -1971,7 +2140,7 @@ static int UpdateShapedJson (TRI_transaction_collection_t* trxCollection,
static int RemoveIndexes (TRI_transaction_collection_t* trxCollection, static int RemoveIndexes (TRI_transaction_collection_t* trxCollection,
TRI_doc_update_policy_t const* policy, TRI_doc_update_policy_t const* policy,
triagens::wal::RemoveMarker const& marker, triagens::wal::RemoveMarker const& marker,
const bool forceSync) { bool forceSync) {
TRI_primary_collection_t* primary = trxCollection->_collection->_collection; TRI_primary_collection_t* primary = trxCollection->_collection->_collection;
@ -3279,12 +3448,14 @@ static bool InitDocumentCollection (TRI_document_collection_t* document,
document->base.figures = Figures; document->base.figures = Figures;
// crud methods // crud methods
document->base.insert = InsertShapedJson;
document->base.insertDocument = InsertDocumentShapedJson; document->base.insertDocument = InsertDocumentShapedJson;
document->base.removeDocument = RemoveDocumentShapedJson;
document->base.updateDocument = UpdateDocumentShapedJson;
document->base.insert = InsertShapedJson;
document->base.read = ReadShapedJson; document->base.read = ReadShapedJson;
document->base.update = UpdateShapedJson; document->base.update = UpdateShapedJson;
document->base.remove = RemoveShapedJson; document->base.remove = RemoveShapedJson;
document->base.removeDocument = RemoveDocumentShapedJson;
// we do not require an initial journal // we do not require an initial journal
document->_requestedJournalSize = 0; document->_requestedJournalSize = 0;

View File

@ -28,11 +28,11 @@
#ifndef TRIAGENS_VOC_BASE_EDGE_COLLECTION_H #ifndef TRIAGENS_VOC_BASE_EDGE_COLLECTION_H
#define TRIAGENS_VOC_BASE_EDGE_COLLECTION_H 1 #define TRIAGENS_VOC_BASE_EDGE_COLLECTION_H 1
#include "VocBase/document-collection.h" #include "Basics/Common.h"
#include "BasicsC/vector.h"
#include "VocBase/voc-types.h"
#ifdef __cplusplus struct TRI_document_collection_s;
extern "C" {
#endif
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- EDGE COLLECTION // --SECTION-- EDGE COLLECTION
@ -42,15 +42,6 @@ extern "C" {
// --SECTION-- public types // --SECTION-- public types
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief typedef for edge flags
/// the type is an integer which indicates the edge direction (IN/OUT)
/// plus two extra bits that indicate whether the edge is self-reflexive and
/// whether the edge is directed
////////////////////////////////////////////////////////////////////////////////
typedef uint32_t TRI_edge_flags_t;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief edge from and to /// @brief edge from and to
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -98,15 +89,11 @@ TRI_edge_header_t;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
TRI_vector_pointer_t TRI_LookupEdgesDocumentCollection ( TRI_vector_pointer_t TRI_LookupEdgesDocumentCollection (
TRI_document_collection_t*, struct TRI_document_collection_s*,
TRI_edge_direction_e, TRI_edge_direction_e,
TRI_voc_cid_t, TRI_voc_cid_t,
TRI_voc_key_t); TRI_voc_key_t);
#ifdef __cplusplus
}
#endif
#endif #endif
// Local Variables: // Local Variables:

View File

@ -329,15 +329,18 @@ typedef struct TRI_primary_collection_s {
void (*dump) (struct TRI_primary_collection_s*); void (*dump) (struct TRI_primary_collection_s*);
#endif #endif
int (*notifyTransaction) (struct TRI_primary_collection_s*, TRI_transaction_status_e); int (*notifyTransaction) (struct TRI_primary_collection_s*, TRI_transaction_status_e);
int (*insert) (struct TRI_transaction_collection_s*, const TRI_voc_key_t, TRI_voc_rid_t, TRI_doc_mptr_t*, TRI_df_marker_type_e, TRI_shaped_json_t const*, void const*, const bool, const bool, const bool); // WAL-based CRUD methods
int (*updateDocument) (struct TRI_transaction_collection_s*, TRI_voc_key_t, TRI_voc_rid_t, TRI_doc_mptr_t*, TRI_shaped_json_t const*, struct TRI_doc_update_policy_s const*, bool, bool);
int (*removeDocument) (struct TRI_transaction_collection_s*, TRI_voc_key_t, TRI_voc_rid_t, struct TRI_doc_update_policy_s const*, bool, bool);
int (*insertDocument) (struct TRI_transaction_collection_s*, TRI_df_marker_type_e, TRI_voc_key_t, TRI_voc_rid_t, TRI_doc_mptr_t*, struct TRI_document_edge_s const*, TRI_shaped_json_t const*, bool, bool, bool); int (*insertDocument) (struct TRI_transaction_collection_s*, TRI_df_marker_type_e, TRI_voc_key_t, TRI_voc_rid_t, TRI_doc_mptr_t*, struct TRI_document_edge_s const*, TRI_shaped_json_t const*, bool, bool, bool);
// old non-WAL-based CRUD methods
int (*insert) (struct TRI_transaction_collection_s*, const TRI_voc_key_t, TRI_voc_rid_t, TRI_doc_mptr_t*, TRI_df_marker_type_e, TRI_shaped_json_t const*, void const*, const bool, const bool, const bool);
int (*read) (struct TRI_transaction_collection_s*, const TRI_voc_key_t, TRI_doc_mptr_t*, const bool); int (*read) (struct TRI_transaction_collection_s*, const TRI_voc_key_t, TRI_doc_mptr_t*, const bool);
int (*update) (struct TRI_transaction_collection_s*, const TRI_voc_key_t, TRI_voc_rid_t, TRI_doc_mptr_t*, TRI_shaped_json_t const*, struct TRI_doc_update_policy_s const*, const bool, const bool); int (*update) (struct TRI_transaction_collection_s*, const TRI_voc_key_t, TRI_voc_rid_t, TRI_doc_mptr_t*, TRI_shaped_json_t const*, struct TRI_doc_update_policy_s const*, const bool, const bool);
int (*remove) (struct TRI_transaction_collection_s*, const TRI_voc_key_t, TRI_voc_rid_t, struct TRI_doc_update_policy_s const*, const bool, const bool); int (*remove) (struct TRI_transaction_collection_s*, const TRI_voc_key_t, TRI_voc_rid_t, struct TRI_doc_update_policy_s const*, const bool, const bool);
int (*removeDocument) (struct TRI_transaction_collection_s*, TRI_voc_key_t, TRI_voc_rid_t, struct TRI_doc_update_policy_s const*, bool, bool);
TRI_doc_collection_info_t* (*figures) (struct TRI_primary_collection_s* collection); TRI_doc_collection_info_t* (*figures) (struct TRI_primary_collection_s* collection);
TRI_voc_size_t (*size) (struct TRI_primary_collection_s* collection); TRI_voc_size_t (*size) (struct TRI_primary_collection_s* collection);

View File

@ -26,6 +26,7 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#include "Marker.h" #include "Marker.h"
#include "VocBase/primary-collection.h"
using namespace triagens::wal; using namespace triagens::wal;
@ -38,7 +39,29 @@ using namespace triagens::wal;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief create marker /// @brief create a copy of a marker
////////////////////////////////////////////////////////////////////////////////
Marker::Marker (Marker&& other)
: _buffer(other._buffer),
_size(other._size) {
other._buffer = nullptr;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief create a copy of a marker
////////////////////////////////////////////////////////////////////////////////
Marker::Marker (Marker const& other)
: _buffer(new char[other._size]),
_size(other._size) {
memcpy(_buffer, other._buffer, other._size);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief create marker with a sized buffer
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Marker::Marker (TRI_df_marker_type_e type, Marker::Marker (TRI_df_marker_type_e type,
@ -242,6 +265,48 @@ void DocumentMarker::dump () const {
<< "\n"; << "\n";
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief clone a marker from another marker
////////////////////////////////////////////////////////////////////////////////
DocumentMarker DocumentMarker::clone (TRI_df_marker_t const* other,
TRI_voc_tick_t databaseId,
TRI_voc_cid_t collectionId,
TRI_voc_rid_t revisionId,
TRI_voc_tid_t transactionId,
triagens::basics::JsonLegend& legend,
TRI_shaped_json_t const* shapedJson) {
char const* base = reinterpret_cast<char const*>(other);
if (other->_type == TRI_DOC_MARKER_KEY_DOCUMENT) {
TRI_doc_document_key_marker_t const* original = reinterpret_cast<TRI_doc_document_key_marker_t const*>(other);
return DocumentMarker(databaseId,
collectionId,
revisionId,
transactionId,
std::string(base + original->_offsetKey),
legend,
shapedJson);
}
else {
assert(other->_type == TRI_WAL_MARKER_DOCUMENT);
document_marker_t const* original = reinterpret_cast<document_marker_t const*>(other);
assert(original->_databaseId == databaseId);
assert(original->_collectionId == collectionId);
return DocumentMarker(original->_databaseId,
original->_collectionId,
revisionId,
transactionId,
std::string(base + original->_offsetKey),
legend,
shapedJson);
}
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- EdgeMarker // --SECTION-- EdgeMarker
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -265,7 +330,6 @@ EdgeMarker::EdgeMarker (TRI_voc_tick_t databaseId,
: Marker(TRI_WAL_MARKER_EDGE, : Marker(TRI_WAL_MARKER_EDGE,
sizeof(edge_marker_t) + alignedSize(key.size() + 1) + alignedSize(strlen(edge->_fromKey) + 1) + alignedSize(strlen(edge->_toKey) + 1) + legend.getSize() + shapedJson->_data.length) { sizeof(edge_marker_t) + alignedSize(key.size() + 1) + alignedSize(strlen(edge->_fromKey) + 1) + alignedSize(strlen(edge->_toKey) + 1) + legend.getSize() + shapedJson->_data.length) {
// document_marker_t* m = reinterpret_cast<document_marker_t*>(base());
edge_marker_t* m = reinterpret_cast<edge_marker_t*>(base()); edge_marker_t* m = reinterpret_cast<edge_marker_t*>(base());
m->_databaseId = databaseId; m->_databaseId = databaseId;
@ -327,6 +391,64 @@ void EdgeMarker::dump () const {
<< "\n"; << "\n";
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief clone a marker from another marker
////////////////////////////////////////////////////////////////////////////////
EdgeMarker EdgeMarker::clone (TRI_df_marker_t const* other,
TRI_voc_tick_t databaseId,
TRI_voc_cid_t collectionId,
TRI_voc_rid_t revisionId,
TRI_voc_tid_t transactionId,
triagens::basics::JsonLegend& legend,
TRI_shaped_json_t const* shapedJson) {
char const* base = reinterpret_cast<char const*>(other);
if (other->_type == TRI_DOC_MARKER_KEY_EDGE) {
TRI_doc_edge_key_marker_t const* original = reinterpret_cast<TRI_doc_edge_key_marker_t const*>(other);
TRI_document_edge_t const edge = {
._fromCid = original->_fromCid,
._toCid = original->_toCid,
._toKey = (TRI_voc_key_t) base + original->_offsetToKey,
._fromKey = (TRI_voc_key_t) base + original->_offsetFromKey
};
return EdgeMarker(databaseId,
collectionId,
revisionId,
transactionId,
std::string(base + original->base._offsetKey),
&edge,
legend,
shapedJson);
}
else {
assert(other->_type == TRI_WAL_MARKER_EDGE);
edge_marker_t const* original = reinterpret_cast<edge_marker_t const*>(other);
assert(original->_databaseId == databaseId);
assert(original->_collectionId == collectionId);
TRI_document_edge_t const edge = {
._fromCid = original->_fromCid,
._toCid = original->_toCid,
._toKey = (TRI_voc_key_t) base + original->_offsetToKey,
._fromKey = (TRI_voc_key_t) base + original->_offsetFromKey
};
return EdgeMarker(original->_databaseId,
original->_collectionId,
revisionId,
transactionId,
std::string(base + original->_offsetKey),
&edge,
legend,
shapedJson);
}
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- RemoveMarker // --SECTION-- RemoveMarker
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@ -124,9 +124,12 @@ namespace triagens {
protected: protected:
Marker (Marker const&) = delete;
Marker& operator= (Marker const&) = delete; Marker& operator= (Marker const&) = delete;
Marker (Marker&&);
Marker (Marker const&);
Marker (TRI_df_marker_type_e, Marker (TRI_df_marker_type_e,
size_t); size_t);
@ -169,9 +172,11 @@ namespace triagens {
size_t); size_t);
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- private variables // --SECTION-- protected variables
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
protected:
char* _buffer; char* _buffer;
uint32_t const _size; uint32_t const _size;
}; };
@ -244,6 +249,14 @@ namespace triagens {
} }
void dump () const; void dump () const;
static DocumentMarker clone (TRI_df_marker_t const*,
TRI_voc_tick_t,
TRI_voc_cid_t,
TRI_voc_rid_t,
TRI_voc_tid_t,
triagens::basics::JsonLegend&,
TRI_shaped_json_t const*);
}; };
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -266,6 +279,14 @@ namespace triagens {
~EdgeMarker (); ~EdgeMarker ();
void dump () const; void dump () const;
static EdgeMarker clone (TRI_df_marker_t const*,
TRI_voc_tick_t,
TRI_voc_cid_t,
TRI_voc_rid_t,
TRI_voc_tid_t,
triagens::basics::JsonLegend&,
TRI_shaped_json_t const*);
}; };
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------