//////////////////////////////////////////////////////////////////////////////// /// @brief vocbase /// /// @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 Dr. Frank Celler /// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany //////////////////////////////////////////////////////////////////////////////// #ifndef TRIAGENS_VOC_BASE_VOCBASE_H #define TRIAGENS_VOC_BASE_VOCBASE_H 1 #include "BasicsC/common.h" #include "BasicsC/associative.h" #include "BasicsC/locks.h" #include "BasicsC/threads.h" #include "BasicsC/vector.h" #include "BasicsC/voc-errors.h" #include "VocBase/vocbase-defaults.h" #ifdef __cplusplus extern "C" { #endif // ----------------------------------------------------------------------------- // --SECTION-- forward declarations // ----------------------------------------------------------------------------- struct TRI_primary_collection_s; struct TRI_col_info_s; struct TRI_general_cursor_store_s; struct TRI_json_s; struct TRI_replication_applier_s; struct TRI_replication_logger_s; struct TRI_server_s; struct TRI_vector_pointer_s; struct TRI_vector_string_s; struct TRI_vocbase_defaults_s; // ----------------------------------------------------------------------------- // --SECTION-- public macros // ----------------------------------------------------------------------------- //////////////////////////////////////////////////////////////////////////////// /// @addtogroup VocBase /// @{ //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /// @brief read locks the collections structure //////////////////////////////////////////////////////////////////////////////// #define TRI_READ_LOCK_COLLECTIONS_VOCBASE(a) \ TRI_ReadLockReadWriteLock(&(a)->_lock) //////////////////////////////////////////////////////////////////////////////// /// @brief read unlocks the collections structure //////////////////////////////////////////////////////////////////////////////// #define TRI_READ_UNLOCK_COLLECTIONS_VOCBASE(a) \ TRI_ReadUnlockReadWriteLock(&(a)->_lock) //////////////////////////////////////////////////////////////////////////////// /// @brief write locks the collections structure //////////////////////////////////////////////////////////////////////////////// #define TRI_WRITE_LOCK_COLLECTIONS_VOCBASE(a) \ TRI_WriteLockReadWriteLock(&(a)->_lock) //////////////////////////////////////////////////////////////////////////////// /// @brief write unlocks the collections structure //////////////////////////////////////////////////////////////////////////////// #define TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(a) \ TRI_WriteUnlockReadWriteLock(&(a)->_lock) //////////////////////////////////////////////////////////////////////////////// /// @brief tries to read lock the vocbase collection status //////////////////////////////////////////////////////////////////////////////// #define TRI_TRY_READ_LOCK_STATUS_VOCBASE_COL(a) \ TRI_TryReadLockReadWriteLock(&(a)->_lock) //////////////////////////////////////////////////////////////////////////////// /// @brief read locks the vocbase collection status //////////////////////////////////////////////////////////////////////////////// #define TRI_READ_LOCK_STATUS_VOCBASE_COL(a) \ TRI_ReadLockReadWriteLock(&(a)->_lock) //////////////////////////////////////////////////////////////////////////////// /// @brief read unlocks the vocbase collection status //////////////////////////////////////////////////////////////////////////////// #define TRI_READ_UNLOCK_STATUS_VOCBASE_COL(a) \ TRI_ReadUnlockReadWriteLock(&(a)->_lock) //////////////////////////////////////////////////////////////////////////////// /// @brief tries to write lock the vocbase collection status //////////////////////////////////////////////////////////////////////////////// #define TRI_TRY_WRITE_LOCK_STATUS_VOCBASE_COL(a) \ TRI_TryWriteLockReadWriteLock(&(a)->_lock) //////////////////////////////////////////////////////////////////////////////// /// @brief write locks the vocbase collection status //////////////////////////////////////////////////////////////////////////////// #define TRI_WRITE_LOCK_STATUS_VOCBASE_COL(a) \ TRI_WriteLockReadWriteLock(&(a)->_lock) //////////////////////////////////////////////////////////////////////////////// /// @brief write unlocks the vocbase collection status //////////////////////////////////////////////////////////////////////////////// #define TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(a) \ TRI_WriteUnlockReadWriteLock(&(a)->_lock) //////////////////////////////////////////////////////////////////////////////// /// @brief write locks the vocbase collection status using spinning //////////////////////////////////////////////////////////////////////////////// #define TRI_EVENTUAL_WRITE_LOCK_STATUS_VOCBASE_COL(a) \ while (! TRI_TRY_WRITE_LOCK_STATUS_VOCBASE_COL(a)) { \ usleep(1000); \ } //////////////////////////////////////////////////////////////////////////////// /// @brief locks the synchroniser waiters //////////////////////////////////////////////////////////////////////////////// #define TRI_LOCK_SYNCHRONISER_WAITER_VOCBASE(a) \ TRI_LockCondition(&(a)->_syncWaitersCondition) //////////////////////////////////////////////////////////////////////////////// /// @brief unlocks the synchroniser waiters //////////////////////////////////////////////////////////////////////////////// #define TRI_UNLOCK_SYNCHRONISER_WAITER_VOCBASE(a) \ TRI_UnlockCondition(&(a)->_syncWaitersCondition) //////////////////////////////////////////////////////////////////////////////// /// @brief waits for synchroniser waiters //////////////////////////////////////////////////////////////////////////////// #define TRI_WAIT_SYNCHRONISER_WAITER_VOCBASE(a, b) \ TRI_TimedWaitCondition(&(a)->_syncWaitersCondition, (b)) //////////////////////////////////////////////////////////////////////////////// /// @brief signals the synchroniser waiters //////////////////////////////////////////////////////////////////////////////// #define TRI_BROADCAST_SYNCHRONISER_WAITER_VOCBASE(a) \ TRI_BroadcastCondition(&(a)->_syncWaitersCondition) //////////////////////////////////////////////////////////////////////////////// /// @brief reduces the number of sync waiters //////////////////////////////////////////////////////////////////////////////// #define TRI_DEC_SYNCHRONISER_WAITER_VOCBASE(a) \ TRI_LockCondition(&(a)->_syncWaitersCondition); \ --((a)->_syncWaiters); \ TRI_UnlockCondition(&(a)->_syncWaitersCondition) //////////////////////////////////////////////////////////////////////////////// /// @brief reduces the number of sync waiters //////////////////////////////////////////////////////////////////////////////// #define TRI_INC_SYNCHRONISER_WAITER_VOCBASE(a) \ TRI_LockCondition(&(a)->_syncWaitersCondition); \ ++((a)->_syncWaiters); \ TRI_BroadcastCondition(&(a)->_syncWaitersCondition); \ TRI_UnlockCondition(&(a)->_syncWaitersCondition) //////////////////////////////////////////////////////////////////////////////// /// @} //////////////////////////////////////////////////////////////////////////////// // ----------------------------------------------------------------------------- // --SECTION-- public constants // ----------------------------------------------------------------------------- //////////////////////////////////////////////////////////////////////////////// /// @addtogroup VocBase /// @{ //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /// @brief name of the _from attribute //////////////////////////////////////////////////////////////////////////////// #define TRI_VOC_ATTRIBUTE_FROM "_from" //////////////////////////////////////////////////////////////////////////////// /// @brief name of the _to attribute //////////////////////////////////////////////////////////////////////////////// #define TRI_VOC_ATTRIBUTE_TO "_to" //////////////////////////////////////////////////////////////////////////////// /// @brief name of the _key attribute //////////////////////////////////////////////////////////////////////////////// #define TRI_VOC_ATTRIBUTE_KEY "_key" //////////////////////////////////////////////////////////////////////////////// /// @brief name of the _rev attribute //////////////////////////////////////////////////////////////////////////////// #define TRI_VOC_ATTRIBUTE_REV "_rev" //////////////////////////////////////////////////////////////////////////////// /// @brief name of the system database //////////////////////////////////////////////////////////////////////////////// #define TRI_VOC_SYSTEM_DATABASE "_system" //////////////////////////////////////////////////////////////////////////////// /// @brief maximal path length //////////////////////////////////////////////////////////////////////////////// #define TRI_COL_PATH_LENGTH (512) //////////////////////////////////////////////////////////////////////////////// /// @brief maximal name length //////////////////////////////////////////////////////////////////////////////// #define TRI_COL_NAME_LENGTH (64) //////////////////////////////////////////////////////////////////////////////// /// @brief default maximal collection journal size //////////////////////////////////////////////////////////////////////////////// #define TRI_JOURNAL_DEFAULT_MAXIMAL_SIZE (1024 * 1024 * 32) //////////////////////////////////////////////////////////////////////////////// /// @brief minimal collection journal size (for testing, we allow very small /// file sizes in maintainer mode) //////////////////////////////////////////////////////////////////////////////// #ifdef TRI_ENABLE_MAINTAINER_MODE #define TRI_JOURNAL_MINIMAL_SIZE (16 * 1024) #else #define TRI_JOURNAL_MINIMAL_SIZE (1024 * 1024) #endif //////////////////////////////////////////////////////////////////////////////// /// @brief journal overhead //////////////////////////////////////////////////////////////////////////////// #define TRI_JOURNAL_OVERHEAD (sizeof(TRI_df_header_marker_t) + sizeof(TRI_df_footer_marker_t)) //////////////////////////////////////////////////////////////////////////////// /// @brief document handle separator as character //////////////////////////////////////////////////////////////////////////////// #define TRI_DOCUMENT_HANDLE_SEPARATOR_CHR '/' //////////////////////////////////////////////////////////////////////////////// /// @brief document handle separator as string //////////////////////////////////////////////////////////////////////////////// #define TRI_DOCUMENT_HANDLE_SEPARATOR_STR "/" //////////////////////////////////////////////////////////////////////////////// /// @brief index handle separator as character //////////////////////////////////////////////////////////////////////////////// #define TRI_INDEX_HANDLE_SEPARATOR_CHR '/' //////////////////////////////////////////////////////////////////////////////// /// @brief index handle separator as string //////////////////////////////////////////////////////////////////////////////// #define TRI_INDEX_HANDLE_SEPARATOR_STR "/" //////////////////////////////////////////////////////////////////////////////// /// @brief no limit //////////////////////////////////////////////////////////////////////////////// #define TRI_QRY_NO_LIMIT ((TRI_voc_size_t) (4294967295U)) //////////////////////////////////////////////////////////////////////////////// /// @brief no skip //////////////////////////////////////////////////////////////////////////////// #define TRI_QRY_NO_SKIP ((TRI_voc_ssize_t) 0) //////////////////////////////////////////////////////////////////////////////// /// @} //////////////////////////////////////////////////////////////////////////////// // ----------------------------------------------------------------------------- // --SECTION-- public types // ----------------------------------------------------------------------------- //////////////////////////////////////////////////////////////////////////////// /// @addtogroup VocBase /// @{ //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /// @brief database /// /// For the lock handling, see the document "LOCKS.md". //////////////////////////////////////////////////////////////////////////////// typedef struct TRI_vocbase_s { TRI_voc_tick_t _id; // internal database id char* _path; // path to the data directory char* _name; // database name struct { TRI_spin_t _lock; // a lock protecting the usage information uint32_t _refCount; // reference counter bool _isDeleted; // flag if database is marked as deleted } _usage; TRI_vocbase_defaults_t _settings; TRI_read_write_lock_t _lock; // collection iterator lock TRI_vector_pointer_t _collections; // pointers to ALL collections TRI_vector_pointer_t _deadCollections; // pointers to collections dropped that can be removed later TRI_associative_pointer_t _collectionsByName; // collections by name TRI_associative_pointer_t _collectionsById; // collections by id TRI_read_write_lock_t _inventoryLock; // object lock needed when replication is assessing the state of the vocbase TRI_associative_pointer_t _authInfo; TRI_associative_pointer_t _authCache; TRI_read_write_lock_t _authInfoLock; bool _authInfoLoaded; // flag indicating whether the authentication info was loaded successfully struct TRI_replication_logger_s* _replicationLogger; struct TRI_replication_applier_s* _replicationApplier; // state of the database // 0 = inactive // 1 = normal operation/running // 2 = shutdown in progress/waiting for compactor/synchroniser thread to finish // 3 = shutdown in progress/waiting for cleanup thread to finish sig_atomic_t _state; TRI_thread_t _synchroniser; TRI_thread_t _compactor; TRI_thread_t _cleanup; #ifdef TRI_SKIPLIST_EX // the index garbage collection TRI_thread_t _indexGC; #endif struct TRI_general_cursor_store_s* _cursors; TRI_associative_pointer_t* _functions; struct { TRI_read_write_lock_t _lock; TRI_vector_t _data; } _compactionBlockers; TRI_condition_t _compactorCondition; TRI_condition_t _cleanupCondition; TRI_condition_t _syncWaitersCondition; int64_t _syncWaiters; } TRI_vocbase_t; //////////////////////////////////////////////////////////////////////////////// /// @brief status of a collection /// /// note: the NEW_BORN status is not used in ArangoDB 1.3 anymore, but is left /// in this enum for compatibility with earlier versions //////////////////////////////////////////////////////////////////////////////// typedef enum { TRI_VOC_COL_STATUS_CORRUPTED = 0, TRI_VOC_COL_STATUS_NEW_BORN = 1, // DEPRECATED, and shouldn't be used anymore TRI_VOC_COL_STATUS_UNLOADED = 2, TRI_VOC_COL_STATUS_LOADED = 3, TRI_VOC_COL_STATUS_UNLOADING = 4, TRI_VOC_COL_STATUS_DELETED = 5 } TRI_vocbase_col_status_e; //////////////////////////////////////////////////////////////////////////////// /// @brief collection container /// /// For the lock, handling see the document "LOCKS.md". //////////////////////////////////////////////////////////////////////////////// typedef struct TRI_vocbase_col_s { TRI_vocbase_t* const _vocbase; TRI_col_type_t const _type; // collection type TRI_voc_cid_t const _cid; // collecttion identifier TRI_read_write_lock_t _lock; // lock protecting the status and name TRI_vocbase_col_status_e _status; // status of the collection struct TRI_primary_collection_s* _collection; // NULL or pointer to loaded collection char _name[TRI_COL_NAME_LENGTH + 1]; // name of the collection char _path[TRI_COL_PATH_LENGTH + 1]; // path to the collection files bool _canDrop; // true if the collection can be dropped bool _canUnload; // true if the collection can be unloaded bool _canRename; // true if the collection can be renamed } TRI_vocbase_col_t; //////////////////////////////////////////////////////////////////////////////// /// @} //////////////////////////////////////////////////////////////////////////////// // ----------------------------------------------------------------------------- // --SECTION-- public functions // ----------------------------------------------------------------------------- //////////////////////////////////////////////////////////////////////////////// /// @addtogroup VocBase /// @{ //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /// @brief free the memory associated with a collection //////////////////////////////////////////////////////////////////////////////// void TRI_FreeCollectionVocBase (TRI_vocbase_col_t*); //////////////////////////////////////////////////////////////////////////////// /// @brief free the memory associated with all collections in a vector //////////////////////////////////////////////////////////////////////////////// void TRI_FreeCollectionsVocBase (struct TRI_vector_pointer_s*); //////////////////////////////////////////////////////////////////////////////// /// @brief opens an existing database, loads all collections //////////////////////////////////////////////////////////////////////////////// TRI_vocbase_t* TRI_OpenVocBase (struct TRI_server_s*, char const*, TRI_voc_tick_t, char const*, struct TRI_vocbase_defaults_s const*, bool); //////////////////////////////////////////////////////////////////////////////// /// @brief closes a database and all collections //////////////////////////////////////////////////////////////////////////////// void TRI_DestroyVocBase (TRI_vocbase_t*); //////////////////////////////////////////////////////////////////////////////// /// @brief load authentication information //////////////////////////////////////////////////////////////////////////////// void TRI_LoadAuthInfoVocBase (TRI_vocbase_t*); //////////////////////////////////////////////////////////////////////////////// /// @brief returns all known collections //////////////////////////////////////////////////////////////////////////////// TRI_vector_pointer_t TRI_CollectionsVocBase (TRI_vocbase_t*); //////////////////////////////////////////////////////////////////////////////// /// @brief returns names of all known collections //////////////////////////////////////////////////////////////////////////////// TRI_vector_string_t TRI_CollectionNamesVocBase (TRI_vocbase_t*); //////////////////////////////////////////////////////////////////////////////// /// @brief returns all known (document) collections with their parameters /// and optionally indexes //////////////////////////////////////////////////////////////////////////////// struct TRI_json_s* TRI_InventoryCollectionsVocBase (TRI_vocbase_t*, TRI_voc_tick_t, bool (*)(TRI_vocbase_col_t*, void*), void*); //////////////////////////////////////////////////////////////////////////////// /// @brief get a collection name by a collection id /// /// the name is fetched under a lock to make this thread-safe. returns NULL if /// the collection does not exist /// it is the caller's responsibility to free the name returned //////////////////////////////////////////////////////////////////////////////// char* TRI_GetCollectionNameByIdVocBase (TRI_vocbase_t*, const TRI_voc_cid_t); //////////////////////////////////////////////////////////////////////////////// /// @brief looks up a (document) collection by name //////////////////////////////////////////////////////////////////////////////// TRI_vocbase_col_t* TRI_LookupCollectionByNameVocBase (TRI_vocbase_t*, char const*); //////////////////////////////////////////////////////////////////////////////// /// @brief looks up a (document) collection by identifier //////////////////////////////////////////////////////////////////////////////// TRI_vocbase_col_t* TRI_LookupCollectionByIdVocBase (TRI_vocbase_t*, TRI_voc_cid_t); //////////////////////////////////////////////////////////////////////////////// /// @brief finds a collection by name or creates it //////////////////////////////////////////////////////////////////////////////// TRI_vocbase_col_t* TRI_FindCollectionByNameOrCreateVocBase (TRI_vocbase_t*, char const*, const TRI_col_type_t, TRI_server_id_t); //////////////////////////////////////////////////////////////////////////////// /// @brief creates a new (document) collection from parameter set //////////////////////////////////////////////////////////////////////////////// TRI_vocbase_col_t* TRI_CreateCollectionVocBase (TRI_vocbase_t*, struct TRI_col_info_s*, TRI_voc_cid_t cid, TRI_server_id_t); //////////////////////////////////////////////////////////////////////////////// /// @brief unloads a (document) collection //////////////////////////////////////////////////////////////////////////////// int TRI_UnloadCollectionVocBase (TRI_vocbase_t*, TRI_vocbase_col_t*, bool); //////////////////////////////////////////////////////////////////////////////// /// @brief drops a (document) collection //////////////////////////////////////////////////////////////////////////////// int TRI_DropCollectionVocBase (TRI_vocbase_t*, TRI_vocbase_col_t*, TRI_server_id_t); //////////////////////////////////////////////////////////////////////////////// /// @brief renames a (document) collection //////////////////////////////////////////////////////////////////////////////// int TRI_RenameCollectionVocBase (TRI_vocbase_t*, TRI_vocbase_col_t*, char const*, bool, TRI_server_id_t); //////////////////////////////////////////////////////////////////////////////// /// @brief locks a (document) collection for usage, loading or manifesting it /// /// Note that this will READ lock the collection you have to release the /// collection lock by yourself. //////////////////////////////////////////////////////////////////////////////// int TRI_UseCollectionVocBase (TRI_vocbase_t*, TRI_vocbase_col_t*); //////////////////////////////////////////////////////////////////////////////// /// @brief locks a (document) collection for usage by id /// /// Note that this will READ lock the collection you have to release the /// collection lock by yourself and call @ref TRI_ReleaseCollectionVocBase /// when you are done with the collection. //////////////////////////////////////////////////////////////////////////////// TRI_vocbase_col_t* TRI_UseCollectionByIdVocBase (TRI_vocbase_t*, const TRI_voc_cid_t); //////////////////////////////////////////////////////////////////////////////// /// @brief locks a (document) collection for usage by name /// /// Note that this will READ lock the collection you have to release the /// collection lock by yourself and call @ref TRI_ReleaseCollectionVocBase /// when you are done with the collection. //////////////////////////////////////////////////////////////////////////////// TRI_vocbase_col_t* TRI_UseCollectionByNameVocBase (TRI_vocbase_t*, char const*); //////////////////////////////////////////////////////////////////////////////// /// @brief releases a (document) collection from usage //////////////////////////////////////////////////////////////////////////////// void TRI_ReleaseCollectionVocBase (TRI_vocbase_t*, TRI_vocbase_col_t*); //////////////////////////////////////////////////////////////////////////////// /// @brief increase the reference counter for a database //////////////////////////////////////////////////////////////////////////////// bool TRI_UseVocBase (TRI_vocbase_t*); //////////////////////////////////////////////////////////////////////////////// /// @brief decrease the reference counter for a database //////////////////////////////////////////////////////////////////////////////// void TRI_ReleaseVocBase (TRI_vocbase_t*); //////////////////////////////////////////////////////////////////////////////// /// @brief marks a database as deleted //////////////////////////////////////////////////////////////////////////////// bool TRI_DropVocBase (TRI_vocbase_t*); //////////////////////////////////////////////////////////////////////////////// /// @brief returns whether any references are held on a database //////////////////////////////////////////////////////////////////////////////// bool TRI_IsUsedVocBase (TRI_vocbase_t*); //////////////////////////////////////////////////////////////////////////////// /// @brief returns whether the database can be removed //////////////////////////////////////////////////////////////////////////////// bool TRI_CanRemoveVocBase (TRI_vocbase_t*); //////////////////////////////////////////////////////////////////////////////// /// @brief returns whether the database is the system database //////////////////////////////////////////////////////////////////////////////// bool TRI_IsSystemVocBase (TRI_vocbase_t*); //////////////////////////////////////////////////////////////////////////////// /// @brief checks if a database name is allowed //////////////////////////////////////////////////////////////////////////////// bool TRI_IsAllowedNameVocBase (bool, char const*); //////////////////////////////////////////////////////////////////////////////// /// @} //////////////////////////////////////////////////////////////////////////////// #ifdef __cplusplus } #endif // ----------------------------------------------------------------------------- // --SECTION-- END-OF-FILE // ----------------------------------------------------------------------------- #endif // Local Variables: // mode: outline-minor // outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}" // End: