1
0
Fork 0

Templatified read and write locker. They can now use Cpp11 style locks. Also included distributeShardsLike in AgencyInformation about collections.

This commit is contained in:
Michael Hackstein 2016-09-26 18:29:51 +02:00
parent 36a8aeb291
commit e16e6b6532
5 changed files with 48 additions and 34 deletions

View File

@ -1217,7 +1217,7 @@ TRI_vocbase_t* MMFilesEngine::openExistingDatabase(TRI_voc_tick_t id, std::strin
for (auto const& it : VPackArrayIterator(slice)) {
// we found a collection that is still active
TRI_ASSERT(!it.get("id").isNone() || !it.get("cid").isNone());
arangodb::LogicalCollection* collection = StorageEngine::registerCollection(ConditionalWriteLocker::DoLock(), vocbase.get(), it);
arangodb::LogicalCollection* collection = StorageEngine::registerCollection(ConditionalWriteLocker<ReadWriteLock>::DoLock(), vocbase.get(), it);
registerCollectionPath(vocbase->id(), collection->cid(), collection->path());

View File

@ -421,9 +421,10 @@ LogicalCollection::LogicalCollection(TRI_vocbase_t* vocbase,
"<properties>.journalSize too small");
}
VPackSlice shardKeysSlice = info.get("shardKeys");
bool const isCluster = ServerState::instance()->isRunningInCluster();
if (shardKeysSlice.isNone()) {
// Use default.
_shardKeys.emplace_back(StaticStrings::KeyString);
@ -450,6 +451,11 @@ LogicalCollection::LogicalCollection(TRI_vocbase_t* vocbase,
}
}
}
if (_shardKeys.empty() && !isCluster) {
// Compatibility. Old configs might store empty shard-keys locally.
// This is translated to ["_key"]. In cluster-case this always was forbidden.
_shardKeys.emplace_back(StaticStrings::KeyString);
}
}
}
@ -504,7 +510,6 @@ LogicalCollection::LogicalCollection(TRI_vocbase_t* vocbase,
auto indexesSlice = info.get("indexes");
if (indexesSlice.isArray()) {
bool const isCluster = ServerState::instance()->isRunningInCluster();
for (auto const& v : VPackArrayIterator(indexesSlice)) {
if (arangodb::basics::VelocyPackHelper::getBooleanValue(
v, "error", false)) {
@ -1009,6 +1014,9 @@ void LogicalCollection::toVelocyPackForAgency(VPackBuilder& result) {
result.add("indexBuckets", VPackValue(_indexBuckets));
result.add("replicationFactor", VPackValue(_replicationFactor));
result.add("numberOfShards", VPackValue(_numberOfShards));
if (!_distributeShardsLike.empty()) {
result.add("distributeShardsLike", VPackValue(_distributeShardsLike));
}
if (_keyGenerator != nullptr) {
result.add(VPackValue("keyOptions"));

View File

@ -296,7 +296,7 @@ arangodb::LogicalCollection* TRI_vocbase_t::createCollectionWorker(
}
arangodb::LogicalCollection* collection =
registerCollection(ConditionalWriteLocker::DoNotLock(), parameters);
registerCollection(ConditionalWriteLocker<ReadWriteLock>::DoNotLock(), parameters);
// Register collection cannot return a nullptr.
// If it would return a nullptr it should have thrown instead

View File

@ -42,23 +42,23 @@
#ifdef TRI_SHOW_LOCK_TIME
#define READ_LOCKER(obj, lock) \
arangodb::basics::ReadLocker obj(&lock, __FILE__, __LINE__)
arangodb::basics::ReadLocker<std::decay<decltype (lock)>::type> obj(&lock, __FILE__, __LINE__)
#define READ_LOCKER_EVENTUAL(obj, lock, t) \
arangodb::basics::ReadLocker obj(&lock, t, __FILE__, __LINE__)
arangodb::basics::ReadLocker<std::decay<decltype (lock)>::type> obj(&lock, t, __FILE__, __LINE__)
#else
#define READ_LOCKER(obj, lock) arangodb::basics::ReadLocker obj(&lock)
#define READ_LOCKER(obj, lock) arangodb::basics::ReadLocker<std::decay<decltype (lock)>::type> obj(&lock)
#define READ_LOCKER_EVENTUAL(obj, lock, t) \
arangodb::basics::ReadLocker obj(&lock, t)
arangodb::basics::ReadLocker<std::decay<decltype (lock)>::type> obj(&lock, t)
#endif
#define TRY_READ_LOCKER(obj, lock) arangodb::basics::TryReadLocker obj(&lock)
#define TRY_READ_LOCKER(obj, lock) arangodb::basics::TryReadLocker<std::decay<decltype (lock)>::type> obj(&lock)
#define CONDITIONAL_READ_LOCKER(obj, lock, condition) arangodb::basics::ConditionalReadLocker obj(&lock, (condition))
#define CONDITIONAL_READ_LOCKER(obj, lock, condition) arangodb::basics::ConditionalReadLocker<std::decay<decltype (lock)>::type> obj(&lock, (condition))
namespace arangodb {
namespace basics {
@ -66,6 +66,7 @@ namespace basics {
/// @brief read locker
/// A ReadLocker read-locks a read-write lock during its lifetime and unlocks
/// the lock when it is destroyed.
template<class LockType>
class ReadLocker {
ReadLocker(ReadLocker const&) = delete;
ReadLocker& operator=(ReadLocker const&) = delete;
@ -75,7 +76,7 @@ class ReadLocker {
/// @brief acquires a read-lock
/// The constructors read-locks the lock, the destructors unlocks the lock.
ReadLocker(ReadWriteLock* readWriteLock, char const* file, int line)
ReadLocker(LockType* readWriteLock, char const* file, int line)
: _readWriteLock(readWriteLock), _file(file), _line(line), _isLocked(false) {
double t = TRI_microtime();
lock();
@ -84,7 +85,7 @@ class ReadLocker {
/// @brief acquires a read-lock, with periodic sleeps while not acquired
/// sleep time is specified in nanoseconds
ReadLocker(ReadWriteLock* readWriteLock, uint64_t sleepTime, char const* file,
ReadLocker(LockType* readWriteLock, uint64_t sleepTime, char const* file,
int line)
: _readWriteLock(readWriteLock), _file(file), _line(line), _isLocked(false) {
double t = TRI_microtime();
@ -96,14 +97,14 @@ class ReadLocker {
/// @brief acquires a read-lock
/// The constructors read-locks the lock, the destructors unlocks the lock.
explicit ReadLocker(ReadWriteLock* readWriteLock)
explicit ReadLocker(LockType* readWriteLock)
: _readWriteLock(readWriteLock), _isLocked(false) {
lock();
}
/// @brief acquires a read-lock, with periodic sleeps while not acquired
/// sleep time is specified in nanoseconds
ReadLocker(ReadWriteLock* readWriteLock, uint64_t sleepTime)
ReadLocker(LockType* readWriteLock, uint64_t sleepTime)
: _readWriteLock(readWriteLock), _isLocked(false) {
lockEventual(sleepTime);
}
@ -168,7 +169,7 @@ class ReadLocker {
private:
/// @brief the read-write lock
ReadWriteLock* _readWriteLock;
LockType* _readWriteLock;
#ifdef TRI_SHOW_LOCK_TIME
@ -186,6 +187,7 @@ class ReadLocker {
bool _isLocked;
};
template<class LockType>
class TryReadLocker {
TryReadLocker(TryReadLocker const&) = delete;
TryReadLocker& operator=(TryReadLocker const&) = delete;
@ -194,7 +196,7 @@ class TryReadLocker {
/// @brief tries to acquire a read-lock
/// The constructor tries to read-lock the lock, the destructors unlocks the
/// lock if it was acquired in the constructor
explicit TryReadLocker(ReadWriteLock* readWriteLock)
explicit TryReadLocker(LockType* readWriteLock)
: _readWriteLock(readWriteLock), _isLocked(false) {
_isLocked = _readWriteLock->tryReadLock();
}
@ -251,12 +253,13 @@ class TryReadLocker {
private:
/// @brief the read-write lock
ReadWriteLock* _readWriteLock;
LockType* _readWriteLock;
/// @brief whether or not we acquired the lock
bool _isLocked;
};
template<class LockType>
class ConditionalReadLocker {
ConditionalReadLocker(ConditionalReadLocker const&) = delete;
ConditionalReadLocker& operator=(ConditionalReadLocker const&) = delete;
@ -265,7 +268,7 @@ class ConditionalReadLocker {
/// @brief acquire a read-lock
/// The constructor tries to read-lock the lock, the destructors unlocks the
/// lock if it was acquired in the constructor
ConditionalReadLocker(ReadWriteLock* readWriteLock, bool condition)
ConditionalReadLocker(LockType* readWriteLock, bool condition)
: _readWriteLock(readWriteLock), _isLocked(false) {
if (condition) {
_readWriteLock->readLock();
@ -328,7 +331,7 @@ class ConditionalReadLocker {
private:
/// @brief the read-write lock
ReadWriteLock* _readWriteLock;
LockType* _readWriteLock;
/// @brief whether or not we acquired the lock
bool _isLocked;

View File

@ -42,23 +42,23 @@
#ifdef TRI_SHOW_LOCK_TIME
#define WRITE_LOCKER(obj, lock) \
arangodb::basics::WriteLocker obj(&lock, __FILE__, __LINE__)
arangodb::basics::WriteLocker<std::decay<decltype (lock)>::type> obj(&lock, __FILE__, __LINE__)
#define WRITE_LOCKER_EVENTUAL(obj, lock, t) \
arangodb::basics::WriteLocker obj(&lock, t, __FILE__, __LINE__)
arangodb::basics::WriteLocker<std::decay<decltype (lock)>::type> obj(&lock, t, __FILE__, __LINE__)
#else
#define WRITE_LOCKER(obj, lock) arangodb::basics::WriteLocker obj(&lock)
#define WRITE_LOCKER(obj, lock) arangodb::basics::WriteLocker<std::decay<decltype (lock)>::type> obj(&lock)
#define WRITE_LOCKER_EVENTUAL(obj, lock, t) \
arangodb::basics::WriteLocker obj(&lock, t)
arangodb::basics::WriteLocker<std::decay<decltype (lock)>::type> obj(&lock, t)
#endif
#define TRY_WRITE_LOCKER(obj, lock) arangodb::basics::TryWriteLocker obj(&lock)
#define TRY_WRITE_LOCKER(obj, lock) arangodb::basics::TryWriteLocker<std::decay<decltype (lock)>::type> obj(&lock)
#define CONDITIONAL_WRITE_LOCKER(obj, lock, condition) arangodb::basics::ConditionalWriteLocker obj(&lock, (condition))
#define CONDITIONAL_WRITE_LOCKER(obj, lock, condition) arangodb::basics::ConditionalWriteLocker<std::decay<decltype (lock)>::type> obj(&lock, (condition))
namespace arangodb {
namespace basics {
@ -66,6 +66,7 @@ namespace basics {
/// @brief write locker
/// A WriteLocker write-locks a read-write lock during its lifetime and unlocks
/// the lock when it is destroyed.
template<class LockType>
class WriteLocker {
WriteLocker(WriteLocker const&) = delete;
WriteLocker& operator=(WriteLocker const&) = delete;
@ -75,7 +76,7 @@ class WriteLocker {
/// @brief aquires a write-lock
/// The constructors acquire a write lock, the destructor unlocks the lock.
WriteLocker(ReadWriteLock* readWriteLock, char const* file, int line)
WriteLocker(LockType* readWriteLock, char const* file, int line)
: _readWriteLock(readWriteLock), _file(file), _line(line), _isLocked(false) {
double t = TRI_microtime();
lock();
@ -84,7 +85,7 @@ class WriteLocker {
/// @brief aquires a write-lock, with periodic sleeps while not acquired
/// sleep time is specified in nanoseconds
WriteLocker(ReadWriteLock* readWriteLock, uint64_t sleepTime,
WriteLocker(LockType* readWriteLock, uint64_t sleepTime,
char const* file, int line)
: _readWriteLock(readWriteLock), _file(file), _line(line), _isLocked(false) {
double t = TRI_microtime();
@ -96,14 +97,14 @@ class WriteLocker {
/// @brief aquires a write-lock
/// The constructors acquire a write lock, the destructor unlocks the lock.
explicit WriteLocker(ReadWriteLock* readWriteLock)
explicit WriteLocker(LockType* readWriteLock)
: _readWriteLock(readWriteLock), _isLocked(false) {
lock();
}
/// @brief aquires a write-lock, with periodic sleeps while not acquired
/// sleep time is specified in nanoseconds
WriteLocker(ReadWriteLock* readWriteLock, uint64_t sleepTime)
WriteLocker(LockType* readWriteLock, uint64_t sleepTime)
: _readWriteLock(readWriteLock), _isLocked(false) {
lockEventual(sleepTime);
_isLocked = true;
@ -166,7 +167,7 @@ class WriteLocker {
private:
/// @brief the read-write lock
ReadWriteLock* _readWriteLock;
LockType* _readWriteLock;
#ifdef TRI_SHOW_LOCK_TIME
@ -185,6 +186,7 @@ class WriteLocker {
bool _isLocked;
};
template<class LockType>
class TryWriteLocker {
TryWriteLocker(TryWriteLocker const&) = delete;
TryWriteLocker& operator=(TryWriteLocker const&) = delete;
@ -193,7 +195,7 @@ class TryWriteLocker {
/// @brief tries to acquire a write-lock
/// The constructor tries to aquire a write lock, the destructors unlocks the
/// lock if we acquired it in the constructor
explicit TryWriteLocker(ReadWriteLock* readWriteLock)
explicit TryWriteLocker(LockType* readWriteLock)
: _readWriteLock(readWriteLock), _isLocked(false) {
_isLocked = _readWriteLock->tryWriteLock();
}
@ -247,12 +249,13 @@ class TryWriteLocker {
private:
/// @brief the read-write lock
ReadWriteLock* _readWriteLock;
LockType* _readWriteLock;
/// @brief whether or not we acquired the lock
bool _isLocked;
};
template<class LockType>
class ConditionalWriteLocker {
ConditionalWriteLocker(ConditionalWriteLocker const&) = delete;
ConditionalWriteLocker& operator=(ConditionalWriteLocker const&) = delete;
@ -261,7 +264,7 @@ class ConditionalWriteLocker {
/// @brief acquire a write-lock
/// The constructor tries to write-lock the lock, the destructor unlocks the
/// lock if it was acquired in the constructor
ConditionalWriteLocker(ReadWriteLock* readWriteLock, bool condition)
ConditionalWriteLocker(LockType* readWriteLock, bool condition)
: _readWriteLock(readWriteLock), _isLocked(false) {
if (condition) {
_readWriteLock->writeLock();
@ -321,7 +324,7 @@ class ConditionalWriteLocker {
private:
/// @brief the read-write lock
ReadWriteLock* _readWriteLock;
LockType* _readWriteLock;
/// @brief whether or not we acquired the lock
bool _isLocked;