mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of github.com:triAGENS/ArangoDB into devel
This commit is contained in:
commit
39d0c506a4
|
@ -604,331 +604,6 @@ TRI_shadow_t* TRI_StoreShadowData (TRI_shadow_store_t* const store,
|
||||||
/// @}
|
/// @}
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/*
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// --SECTION-- UNUSED AND UNTESTED CODE FOLLOWS
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// --SECTION-- SHADOW DOCUMENTS
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// --SECTION-- private functions
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @addtogroup VocBase
|
|
||||||
/// @{
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief hashes an element
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static uint64_t HashShadowDocumentElement (TRI_associative_pointer_t* array,
|
|
||||||
void const* e) {
|
|
||||||
TRI_shadow_document_t const* element = e;
|
|
||||||
|
|
||||||
return element->_did;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief tests if two elements are equal
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static bool EqualShadowDocumentElement (TRI_associative_pointer_t* array,
|
|
||||||
void const* l,
|
|
||||||
void const* r) {
|
|
||||||
TRI_shadow_document_t const* left = l;
|
|
||||||
TRI_shadow_document_t const* right = r;
|
|
||||||
|
|
||||||
return ((left->_base->_id == right->_base->_id) ||
|
|
||||||
(left->_cid == right->_cid && left->_did == right->_did));
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief creates a shadow document data structure
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static TRI_shadow_document_t* CreateShadowDocument (void* const element,
|
|
||||||
TRI_voc_cid_t cid,
|
|
||||||
TRI_voc_did_t did,
|
|
||||||
TRI_voc_rid_t rid) {
|
|
||||||
TRI_shadow_document_t* shadow;
|
|
||||||
TRI_shadow_t* base = CreateShadow(element);
|
|
||||||
|
|
||||||
if (!base) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
shadow = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_shadow_document_t), false);
|
|
||||||
if (!shadow) {
|
|
||||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, base);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
shadow->_base = base;
|
|
||||||
shadow->_cid = cid;
|
|
||||||
shadow->_did = did;
|
|
||||||
shadow->_rid = rid;
|
|
||||||
|
|
||||||
return shadow;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief looks up a shadow document or creates it
|
|
||||||
///
|
|
||||||
/// Note: this function is called under an exclusive lock on the index
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static TRI_shadow_document_t* LookupShadowDocument (TRI_shadow_document_store_t* const store,
|
|
||||||
TRI_doc_collection_t* collection,
|
|
||||||
TRI_doc_mptr_t const* mptr,
|
|
||||||
TRI_voc_cid_t cid,
|
|
||||||
TRI_voc_did_t did) {
|
|
||||||
union { TRI_shadow_document_t* s; TRI_shadow_document_t const* c; } cnv;
|
|
||||||
TRI_shadow_document_t* shadow;
|
|
||||||
TRI_shadow_document_t search;
|
|
||||||
void* element;
|
|
||||||
|
|
||||||
// check if we already know a parsed version
|
|
||||||
search._cid = cid;
|
|
||||||
search._did = did;
|
|
||||||
cnv.c = TRI_LookupByElementAssociativePointer(&store->_base->_index, &search);
|
|
||||||
shadow = cnv.s;
|
|
||||||
|
|
||||||
if (shadow) {
|
|
||||||
bool ok = store->verifyShadow(store, collection, mptr, shadow->_base->_data);
|
|
||||||
if (ok) {
|
|
||||||
++shadow->_base->_rc;
|
|
||||||
UpdateTimestampShadow(shadow->_base);
|
|
||||||
return shadow;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
TRI_ReleaseShadowDocument(store, shadow);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse the document
|
|
||||||
element = store->createShadow(store, collection, mptr);
|
|
||||||
if (!element) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
shadow = CreateShadowDocument(element, cid, did, mptr->_rid);
|
|
||||||
if (shadow) {
|
|
||||||
// enter the element into the store
|
|
||||||
TRI_InsertElementAssociativePointer(&store->_base->_index, shadow, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// might be NULL
|
|
||||||
return shadow;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @}
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// --SECTION-- constructors and destructors
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @addtogroup VocBase
|
|
||||||
/// @{
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief initialises a shadow document storage
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TRI_shadow_document_store_t* TRI_CreateShadowDocumentStore (
|
|
||||||
void* (*create) (TRI_shadow_document_store_t*, TRI_doc_collection_t*, TRI_doc_mptr_t const*),
|
|
||||||
bool (*verify) (TRI_shadow_document_store_t*, TRI_doc_collection_t*, TRI_doc_mptr_t const*, void*),
|
|
||||||
void (*destroy) (TRI_shadow_document_store_t*, TRI_shadow_document_t*)) {
|
|
||||||
|
|
||||||
TRI_shadow_document_store_t* store;
|
|
||||||
TRI_shadow_store_t* base;
|
|
||||||
|
|
||||||
base = (TRI_shadow_store_t*) TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_shadow_store_t), false);
|
|
||||||
if (!base) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
TRI_InitAssociativePointer(&base->_index,
|
|
||||||
NULL,
|
|
||||||
HashShadowDocumentElement,
|
|
||||||
NULL,
|
|
||||||
EqualShadowDocumentElement);
|
|
||||||
|
|
||||||
store = (TRI_shadow_document_store_t*) TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_shadow_document_store_t), false);
|
|
||||||
if (!store) {
|
|
||||||
TRI_FreeShadowStore(base);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
store->_base = base;
|
|
||||||
|
|
||||||
TRI_InitMutex(&store->_base->_lock);
|
|
||||||
|
|
||||||
store->createShadow = create;
|
|
||||||
store->verifyShadow = verify;
|
|
||||||
store->destroyShadow = destroy;
|
|
||||||
|
|
||||||
return store;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief destroys a shadow document storage
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void TRI_FreeShadowDocumentStore (TRI_shadow_document_store_t* const store) {
|
|
||||||
assert(store);
|
|
||||||
|
|
||||||
TRI_FreeShadowStore(store->_base);
|
|
||||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, store);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @}
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// --SECTION-- public methods
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @addtogroup VocBase
|
|
||||||
/// @{
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief looks up or creates a shadow document
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TRI_shadow_document_t* TRI_FindShadowDocument (TRI_shadow_document_store_t* const store,
|
|
||||||
TRI_vocbase_t* vocbase,
|
|
||||||
TRI_voc_cid_t cid,
|
|
||||||
TRI_voc_did_t did) {
|
|
||||||
TRI_vocbase_col_t const* col;
|
|
||||||
TRI_doc_collection_t* collection;
|
|
||||||
TRI_doc_mptr_t const* mptr;
|
|
||||||
TRI_shadow_document_t* shadow;
|
|
||||||
|
|
||||||
assert(store);
|
|
||||||
|
|
||||||
// extract the collection
|
|
||||||
col = TRI_LookupCollectionByIdVocBase(vocbase, cid);
|
|
||||||
if (!col) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
collection = col->_collection;
|
|
||||||
|
|
||||||
// lock the collection
|
|
||||||
collection->beginRead(collection);
|
|
||||||
|
|
||||||
// find the document
|
|
||||||
mptr = collection->read(collection, did);
|
|
||||||
|
|
||||||
shadow = NULL;
|
|
||||||
if (mptr) {
|
|
||||||
TRI_LockMutex(&store->_base->_lock);
|
|
||||||
shadow = LookupShadowDocument(store, collection, mptr, cid, did);
|
|
||||||
TRI_UnlockMutex(&store->_base->_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
// unlock the collection
|
|
||||||
collection->endRead(collection);
|
|
||||||
|
|
||||||
// might be null
|
|
||||||
return shadow;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief releases a shadow document
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
bool TRI_ReleaseShadowDocument (TRI_shadow_document_store_t* const store,
|
|
||||||
TRI_shadow_document_t* shadow) {
|
|
||||||
bool result;
|
|
||||||
|
|
||||||
assert(store);
|
|
||||||
|
|
||||||
TRI_LockMutex(&store->_base->_lock);
|
|
||||||
|
|
||||||
// release the element
|
|
||||||
--shadow->_base->_rc;
|
|
||||||
|
|
||||||
// need to destroy the element
|
|
||||||
if (shadow->_base->_rc < 1) {
|
|
||||||
TRI_RemoveElementAssociativePointer(&store->_base->_index, shadow);
|
|
||||||
store->destroyShadow(store, shadow);
|
|
||||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, shadow->_base);
|
|
||||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, shadow);
|
|
||||||
result = true; // object was destroyed
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result = false; // object was not destroyed
|
|
||||||
}
|
|
||||||
|
|
||||||
TRI_UnlockMutex(&store->_base->_lock);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief enumerate all shadows and remove them if expired
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void TRI_CleanupShadowDocuments (TRI_shadow_document_store_t* const store, const double maxAge) {
|
|
||||||
double compareStamp = TRI_microtime() - maxAge; // age must be specified in secs
|
|
||||||
size_t deleteCount = 0;
|
|
||||||
|
|
||||||
// we need an exclusive lock on the index
|
|
||||||
TRI_LockMutex(&store->_base->_lock);
|
|
||||||
|
|
||||||
// loop until there's nothing to delete or
|
|
||||||
// we have deleted SHADOW_MAX_DELETE elements
|
|
||||||
while (deleteCount++ < SHADOW_MAX_DELETE) {
|
|
||||||
bool deleted = false;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < store->_base->_index._nrAlloc; i++) {
|
|
||||||
// enum all shadows
|
|
||||||
TRI_shadow_t* shadow = (TRI_shadow_t*) store->_base->_index._table[i];
|
|
||||||
if (!shadow) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if shadow is unused and expired
|
|
||||||
if (shadow->_rc <= 1 && shadow->_timestamp < compareStamp) {
|
|
||||||
LOG_DEBUG("cleaning expired shadow %p", shadow);
|
|
||||||
TRI_RemoveElementAssociativePointer(&store->_base->_index, shadow);
|
|
||||||
// store->destroyShadow(store, shadow);
|
|
||||||
// TRI_Free(TRI_UNKNOWN_MEM_ZONE, shadow);
|
|
||||||
|
|
||||||
deleted = true;
|
|
||||||
// the remove might reposition elements in the container.
|
|
||||||
// therefore break here and start iteration anew
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!deleted) {
|
|
||||||
// we did not find anything to delete, so give up
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// release lock
|
|
||||||
TRI_UnlockMutex(&store->_base->_lock);
|
|
||||||
}
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @}
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Local Variables:
|
// Local Variables:
|
||||||
// mode: outline-minor
|
// mode: outline-minor
|
||||||
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)"
|
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)"
|
||||||
|
|
|
@ -33,7 +33,6 @@
|
||||||
#include <BasicsC/associative.h>
|
#include <BasicsC/associative.h>
|
||||||
|
|
||||||
#include "VocBase/vocbase.h"
|
#include "VocBase/vocbase.h"
|
||||||
#include "VocBase/document-collection.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -252,106 +251,6 @@ TRI_shadow_t* TRI_StoreShadowData (TRI_shadow_store_t* const,
|
||||||
/// @}
|
/// @}
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/*
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// --SECTION-- UNUSED AND UNTESTED CODE FOLLOWS
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// --SECTION-- SHADOW DOCUMENTS
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// --SECTION-- constructors and destructors
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @addtogroup VocBase
|
|
||||||
/// @{
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief shadow document
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
typedef struct TRI_shadow_document_s {
|
|
||||||
TRI_shadow_t* _base;
|
|
||||||
|
|
||||||
TRI_voc_cid_t _cid;
|
|
||||||
TRI_voc_did_t _did;
|
|
||||||
TRI_voc_rid_t _rid;
|
|
||||||
}
|
|
||||||
TRI_shadow_document_t;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief shadow document storage
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
typedef struct TRI_shadow_document_store_s {
|
|
||||||
TRI_shadow_store_t* _base;
|
|
||||||
|
|
||||||
void* (*createShadow) (struct TRI_shadow_document_store_s*, struct TRI_doc_collection_s*, struct TRI_doc_mptr_s const*);
|
|
||||||
bool (*verifyShadow) (struct TRI_shadow_document_store_s*, struct TRI_doc_collection_s*, struct TRI_doc_mptr_s const*, void*);
|
|
||||||
void (*destroyShadow) (struct TRI_shadow_document_store_s*, TRI_shadow_document_t*);
|
|
||||||
}
|
|
||||||
TRI_shadow_document_store_t;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief initialises a shadow document storage
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TRI_shadow_document_store_t* TRI_CreateShadowDocumentStore (
|
|
||||||
void* (*create) (TRI_shadow_document_store_t*, TRI_doc_collection_t*, TRI_doc_mptr_t const*),
|
|
||||||
bool (*verify) (TRI_shadow_document_store_t*, TRI_doc_collection_t*, TRI_doc_mptr_t const*, void*),
|
|
||||||
void (*destroy) (TRI_shadow_document_store_t*, TRI_shadow_document_t*));
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief destroys a shadow document storage
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void TRI_FreeShadowDocumentStore (TRI_shadow_document_store_t* const);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @}
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// --SECTION-- public methods
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @addtogroup VocBase
|
|
||||||
/// @{
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief looks up or creates a shadow document
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TRI_shadow_document_t* TRI_FindShadowDocument (TRI_shadow_document_store_t* const,
|
|
||||||
TRI_vocbase_t*,
|
|
||||||
TRI_voc_cid_t,
|
|
||||||
TRI_voc_did_t);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief releases a shadow document
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
bool TRI_ReleaseShadowDocument (TRI_shadow_document_store_t* const,
|
|
||||||
TRI_shadow_document_t*);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief enumerate all shadows and remove them if expired
|
|
||||||
///
|
|
||||||
/// The max age must be specified in seconds
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void TRI_CleanupShadowDocuments (TRI_shadow_document_store_t* const, const double);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @}
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
*/
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue