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:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)"
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
#include <BasicsC/associative.h>
|
||||
|
||||
#include "VocBase/vocbase.h"
|
||||
#include "VocBase/document-collection.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
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
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue