mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of https://github.com/arangodb/arangodb into devel
This commit is contained in:
commit
68611a0a6a
|
@ -27,6 +27,10 @@
|
||||||
#include "Basics/StaticStrings.h"
|
#include "Basics/StaticStrings.h"
|
||||||
#include "Basics/VelocyPackHelper.h"
|
#include "Basics/VelocyPackHelper.h"
|
||||||
#include "Basics/WriteLocker.h"
|
#include "Basics/WriteLocker.h"
|
||||||
|
#include "Cache/CacheManagerFeature.h"
|
||||||
|
#include "Cache/TransactionalCache.h"
|
||||||
|
#include "Cache/Common.h"
|
||||||
|
#include "Cache/Manager.h"
|
||||||
#include "Cluster/ClusterMethods.h"
|
#include "Cluster/ClusterMethods.h"
|
||||||
#include "Cluster/CollectionLockState.h"
|
#include "Cluster/CollectionLockState.h"
|
||||||
#include "Indexes/Index.h"
|
#include "Indexes/Index.h"
|
||||||
|
@ -82,9 +86,15 @@ RocksDBCollection::RocksDBCollection(LogicalCollection* collection,
|
||||||
_objectId(basics::VelocyPackHelper::stringUInt64(info, "objectId")),
|
_objectId(basics::VelocyPackHelper::stringUInt64(info, "objectId")),
|
||||||
_numberDocuments(0),
|
_numberDocuments(0),
|
||||||
_revisionId(0),
|
_revisionId(0),
|
||||||
_hasGeoIndex(false) {
|
_hasGeoIndex(false),
|
||||||
|
_cache(nullptr),
|
||||||
|
_cachePresent(false),
|
||||||
|
_useCache(true) {
|
||||||
addCollectionMapping(_objectId, _logicalCollection->vocbase()->id(),
|
addCollectionMapping(_objectId, _logicalCollection->vocbase()->id(),
|
||||||
_logicalCollection->cid());
|
_logicalCollection->cid());
|
||||||
|
if (_useCache) {
|
||||||
|
createCache();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RocksDBCollection::RocksDBCollection(LogicalCollection* collection,
|
RocksDBCollection::RocksDBCollection(LogicalCollection* collection,
|
||||||
|
@ -93,12 +103,27 @@ RocksDBCollection::RocksDBCollection(LogicalCollection* collection,
|
||||||
_objectId(static_cast<RocksDBCollection*>(physical)->_objectId),
|
_objectId(static_cast<RocksDBCollection*>(physical)->_objectId),
|
||||||
_numberDocuments(0),
|
_numberDocuments(0),
|
||||||
_revisionId(0),
|
_revisionId(0),
|
||||||
_hasGeoIndex(false) {
|
_hasGeoIndex(false),
|
||||||
|
_cache(nullptr),
|
||||||
|
_cachePresent(false),
|
||||||
|
_useCache(true) {
|
||||||
addCollectionMapping(_objectId, _logicalCollection->vocbase()->id(),
|
addCollectionMapping(_objectId, _logicalCollection->vocbase()->id(),
|
||||||
_logicalCollection->cid());
|
_logicalCollection->cid());
|
||||||
|
if (_useCache) {
|
||||||
|
createCache();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RocksDBCollection::~RocksDBCollection() {}
|
RocksDBCollection::~RocksDBCollection() {
|
||||||
|
if (useCache()) {
|
||||||
|
try {
|
||||||
|
TRI_ASSERT(_cache != nullptr);
|
||||||
|
TRI_ASSERT(CacheManagerFeature::MANAGER != nullptr);
|
||||||
|
CacheManagerFeature::MANAGER->destroyCache(_cache);
|
||||||
|
} catch (...) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string const& RocksDBCollection::path() const {
|
std::string const& RocksDBCollection::path() const {
|
||||||
return Empty; // we do not have any path
|
return Empty; // we do not have any path
|
||||||
|
@ -617,6 +642,8 @@ void RocksDBCollection::truncate(transaction::Methods* trx,
|
||||||
VPackSlice(iter->value().data()).get(StaticStrings::KeyString);
|
VPackSlice(iter->value().data()).get(StaticStrings::KeyString);
|
||||||
TRI_ASSERT(key.isString());
|
TRI_ASSERT(key.isString());
|
||||||
|
|
||||||
|
blackListKey(iter->key().data(), static_cast<uint32_t>(iter->key().size()));
|
||||||
|
|
||||||
// add possible log statement
|
// add possible log statement
|
||||||
state->prepareOperation(cid, revisionId, StringRef(key),
|
state->prepareOperation(cid, revisionId, StringRef(key),
|
||||||
TRI_VOC_DOCUMENT_OPERATION_REMOVE);
|
TRI_VOC_DOCUMENT_OPERATION_REMOVE);
|
||||||
|
@ -1388,6 +1415,8 @@ RocksDBOperationResult RocksDBCollection::insertDocument(
|
||||||
RocksDBKey key(RocksDBKey::Document(_objectId, revisionId));
|
RocksDBKey key(RocksDBKey::Document(_objectId, revisionId));
|
||||||
RocksDBValue value(RocksDBValue::Document(doc));
|
RocksDBValue value(RocksDBValue::Document(doc));
|
||||||
|
|
||||||
|
blackListKey(key.string().data(), static_cast<uint32_t>(key.string().size()));
|
||||||
|
|
||||||
rocksdb::Transaction* rtrx = rocksTransaction(trx);
|
rocksdb::Transaction* rtrx = rocksTransaction(trx);
|
||||||
|
|
||||||
rocksdb::Status status = rtrx->Put(key.string(), value.string());
|
rocksdb::Status status = rtrx->Put(key.string(), value.string());
|
||||||
|
@ -1447,6 +1476,8 @@ RocksDBOperationResult RocksDBCollection::removeDocument(
|
||||||
|
|
||||||
auto key = RocksDBKey::Document(_objectId, revisionId);
|
auto key = RocksDBKey::Document(_objectId, revisionId);
|
||||||
|
|
||||||
|
blackListKey(key.string().data(), static_cast<uint32_t>(key.string().size()));
|
||||||
|
|
||||||
rocksdb::Transaction* rtrx = rocksTransaction(trx);
|
rocksdb::Transaction* rtrx = rocksTransaction(trx);
|
||||||
|
|
||||||
rtrx->PutLogData(RocksDBLogValue::DocumentRemove(
|
rtrx->PutLogData(RocksDBLogValue::DocumentRemove(
|
||||||
|
@ -1551,12 +1582,38 @@ arangodb::Result RocksDBCollection::lookupRevisionVPack(
|
||||||
|
|
||||||
auto key = RocksDBKey::Document(_objectId, revisionId);
|
auto key = RocksDBKey::Document(_objectId, revisionId);
|
||||||
std::string value;
|
std::string value;
|
||||||
|
|
||||||
|
if (useCache()) {
|
||||||
|
TRI_ASSERT(_cache != nullptr);
|
||||||
|
// check cache first for fast path
|
||||||
|
auto f = _cache->find(key.string().data(),
|
||||||
|
static_cast<uint32_t>(key.string().size()));
|
||||||
|
if (f.found()) {
|
||||||
|
value.append(reinterpret_cast<char const*>(f.value()->value()),
|
||||||
|
static_cast<size_t>(f.value()->valueSize));
|
||||||
|
mdr.setManaged(std::move(value), revisionId);
|
||||||
|
return {TRI_ERROR_NO_ERROR};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto* state = toRocksTransactionState(trx);
|
auto* state = toRocksTransactionState(trx);
|
||||||
rocksdb::Status status = state->rocksTransaction()->Get(state->readOptions(),
|
rocksdb::Status status = state->rocksTransaction()->Get(state->readOptions(),
|
||||||
key.string(), &value);
|
key.string(), &value);
|
||||||
TRI_ASSERT(value.data());
|
TRI_ASSERT(value.data());
|
||||||
auto result = convertStatus(status);
|
auto result = convertStatus(status);
|
||||||
if (result.ok()) {
|
if (result.ok()) {
|
||||||
|
if (useCache()) {
|
||||||
|
TRI_ASSERT(_cache != nullptr);
|
||||||
|
// write entry back to cache
|
||||||
|
auto entry = cache::CachedValue::construct(
|
||||||
|
key.string().data(), static_cast<uint32_t>(key.string().size()),
|
||||||
|
value.data(), static_cast<uint64_t>(value.size()));
|
||||||
|
bool cached = _cache->insert(entry);
|
||||||
|
if (!cached) {
|
||||||
|
delete entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mdr.setManaged(std::move(value), revisionId);
|
mdr.setManaged(std::move(value), revisionId);
|
||||||
} else {
|
} else {
|
||||||
mdr.reset();
|
mdr.reset();
|
||||||
|
@ -1745,3 +1802,52 @@ void RocksDBCollection::estimateSize(velocypack::Builder& builder) {
|
||||||
builder.add("total", VPackValue(total));
|
builder.add("total", VPackValue(total));
|
||||||
builder.close();
|
builder.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RocksDBCollection::createCache() const {
|
||||||
|
if (!_useCache || _cachePresent) {
|
||||||
|
// we leave this if we do not need the cache
|
||||||
|
// or if cache already created
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRI_ASSERT(_useCache);
|
||||||
|
TRI_ASSERT(_cache.get() == nullptr);
|
||||||
|
TRI_ASSERT(CacheManagerFeature::MANAGER != nullptr);
|
||||||
|
_cache = CacheManagerFeature::MANAGER->createCache(
|
||||||
|
cache::CacheType::Transactional);
|
||||||
|
_cachePresent = (_cache.get() != nullptr);
|
||||||
|
TRI_ASSERT(_useCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RocksDBCollection::disableCache() const {
|
||||||
|
if (!_cachePresent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
TRI_ASSERT(CacheManagerFeature::MANAGER != nullptr);
|
||||||
|
// must have a cache...
|
||||||
|
TRI_ASSERT(_useCache);
|
||||||
|
TRI_ASSERT(_cachePresent);
|
||||||
|
TRI_ASSERT(_cache.get() != nullptr);
|
||||||
|
CacheManagerFeature::MANAGER->destroyCache(_cache);
|
||||||
|
_cache.reset();
|
||||||
|
_cachePresent = false;
|
||||||
|
TRI_ASSERT(_useCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
// blacklist given key from transactional cache
|
||||||
|
void RocksDBCollection::blackListKey(char const* data, std::size_t len) const {
|
||||||
|
if (useCache()) {
|
||||||
|
TRI_ASSERT(_cache != nullptr);
|
||||||
|
bool blacklisted = false;
|
||||||
|
uint64_t attempts = 0;
|
||||||
|
while (!blacklisted) {
|
||||||
|
blacklisted = _cache->blacklist(data,len);
|
||||||
|
if (attempts++ % 10 == 0) {
|
||||||
|
if (_cache->isShutdown()) {
|
||||||
|
disableCache();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -33,6 +33,9 @@
|
||||||
#include "VocBase/ManagedDocumentResult.h"
|
#include "VocBase/ManagedDocumentResult.h"
|
||||||
|
|
||||||
namespace arangodb {
|
namespace arangodb {
|
||||||
|
namespace cache {
|
||||||
|
class Cache;
|
||||||
|
}
|
||||||
class LogicalCollection;
|
class LogicalCollection;
|
||||||
class ManagedDocumentResult;
|
class ManagedDocumentResult;
|
||||||
class Result;
|
class Result;
|
||||||
|
@ -217,6 +220,11 @@ class RocksDBCollection final : public PhysicalCollection {
|
||||||
arangodb::Result lookupRevisionVPack(TRI_voc_rid_t, transaction::Methods*,
|
arangodb::Result lookupRevisionVPack(TRI_voc_rid_t, transaction::Methods*,
|
||||||
arangodb::ManagedDocumentResult&) const;
|
arangodb::ManagedDocumentResult&) const;
|
||||||
|
|
||||||
|
void createCache() const;
|
||||||
|
void disableCache() const;
|
||||||
|
inline bool useCache() const { return (_useCache && _cachePresent); }
|
||||||
|
void blackListKey(char const* data, std::size_t len) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint64_t const _objectId; // rocksdb-specific object id for collection
|
uint64_t const _objectId; // rocksdb-specific object id for collection
|
||||||
std::atomic<uint64_t> _numberDocuments;
|
std::atomic<uint64_t> _numberDocuments;
|
||||||
|
@ -225,6 +233,12 @@ class RocksDBCollection final : public PhysicalCollection {
|
||||||
/// upgrade write locks to exclusive locks if this flag is set
|
/// upgrade write locks to exclusive locks if this flag is set
|
||||||
bool _hasGeoIndex;
|
bool _hasGeoIndex;
|
||||||
basics::ReadWriteLock _exclusiveLock;
|
basics::ReadWriteLock _exclusiveLock;
|
||||||
|
|
||||||
|
mutable std::shared_ptr<cache::Cache> _cache;
|
||||||
|
// we use this boolean for testing whether _cache is set.
|
||||||
|
// it's quicker than accessing the shared_ptr each time
|
||||||
|
mutable bool _cachePresent;
|
||||||
|
bool _useCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline RocksDBCollection* toRocksDBCollection(PhysicalCollection* physical) {
|
inline RocksDBCollection* toRocksDBCollection(PhysicalCollection* physical) {
|
||||||
|
|
|
@ -58,7 +58,7 @@ RocksDBIndex::RocksDBIndex(
|
||||||
}
|
}
|
||||||
|
|
||||||
RocksDBIndex::RocksDBIndex(TRI_idx_iid_t id, LogicalCollection* collection,
|
RocksDBIndex::RocksDBIndex(TRI_idx_iid_t id, LogicalCollection* collection,
|
||||||
VPackSlice const& info,bool useCache)
|
VPackSlice const& info, bool useCache)
|
||||||
: Index(id, collection, info),
|
: Index(id, collection, info),
|
||||||
_objectId(basics::VelocyPackHelper::stringUInt64(info.get("objectId"))),
|
_objectId(basics::VelocyPackHelper::stringUInt64(info.get("objectId"))),
|
||||||
_cmp(static_cast<RocksDBEngine*>(EngineSelectorFeature::ENGINE)->cmp()),
|
_cmp(static_cast<RocksDBEngine*>(EngineSelectorFeature::ENGINE)->cmp()),
|
||||||
|
|
|
@ -297,14 +297,9 @@ RocksDBPrimaryIndex::RocksDBPrimaryIndex(
|
||||||
{{arangodb::basics::AttributeName(
|
{{arangodb::basics::AttributeName(
|
||||||
StaticStrings::KeyString, false)}}),
|
StaticStrings::KeyString, false)}}),
|
||||||
true, false,
|
true, false,
|
||||||
basics::VelocyPackHelper::stringUInt64(info, "objectId")
|
basics::VelocyPackHelper::stringUInt64(info, "objectId"),
|
||||||
,!ServerState::instance()->isCoordinator() /*useCache*/
|
!ServerState::instance()->isCoordinator() /*useCache*/) {
|
||||||
) {
|
|
||||||
TRI_ASSERT(_objectId != 0);
|
TRI_ASSERT(_objectId != 0);
|
||||||
if (_objectId == 0 ) {
|
|
||||||
//disableCache
|
|
||||||
_useCache = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RocksDBPrimaryIndex::~RocksDBPrimaryIndex() {}
|
RocksDBPrimaryIndex::~RocksDBPrimaryIndex() {}
|
||||||
|
|
Loading…
Reference in New Issue