blob: d86cffb8333a17b29250c519e3e3743a44be1cab [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
**/
#ifndef QUICKSTEP_TRANSACTION_ACCESS_MODE_HPP_
#define QUICKSTEP_TRANSACTION_ACCESS_MODE_HPP_
#include <cstdint>
#include <type_traits>
namespace quickstep {
namespace transaction {
/** \addtogroup Transaction
* @{
*/
/**
* @brief Represents mode type. Possible options are NL, IS, IX, S, SIX, X.
**/
enum class AccessModeType : std::uint8_t {
kNoLockMode = 0,
kIsLockMode,
kIxLockMode,
kSLockMode,
kSixLockMode,
kXLockMode,
kNumAccessModeTypes,
};
/**
* @brief Class for representing resource lock's access mode
**/
class AccessMode {
public:
/**
* @brief Only constructor for access mode.
*
* @param access_mode Mode type of the object.
**/
explicit AccessMode(const AccessModeType access_mode)
: access_mode_(access_mode) {}
/**
* @brief Factory method for NoLockMode.
*
* @return NoLockMode instance.
**/
static AccessMode NoLockMode() {
return AccessMode(AccessModeType::kNoLockMode);
}
/**
* @brief Factory method for IsLockMode.
*
* @return IsLockMode instance.
**/
static AccessMode IsLockMode() {
return AccessMode(AccessModeType::kIsLockMode);
}
/**
* @brief Factory method for IxLockMode.
*
* @return IxLockMode instance.
**/
static AccessMode IxLockMode() {
return AccessMode(AccessModeType::kIxLockMode);
}
/**
* @brief Factory method for SixLockMode.
*
* @return SixLockMode instance.
**/
static AccessMode SixLockMode() {
return AccessMode(AccessModeType::kSixLockMode);
}
/**
* @brief Factory method for SLockMode.
*
* @return SLockMode instance.
**/
static AccessMode SLockMode() {
return AccessMode(AccessModeType::kSLockMode);
}
/**
* @brief Factory method for XLockMode.
*
* @return XLockMode instance.
**/
static AccessMode XLockMode() {
return AccessMode(AccessModeType::kXLockMode);
}
/**
* @brief Checks whether this access mode is compatible with the other.
*
* @param other Other access mode that will be checked against to this one.
* @return True if they are compatible, otherwise false.
**/
inline bool isCompatible(const AccessMode &other) const {
const access_mode_underlying_type this_mode =
static_cast<access_mode_underlying_type>(access_mode_);
const access_mode_underlying_type other_mode =
static_cast<access_mode_underlying_type>(other.access_mode_);
return AccessMode::kLockCompatibilityMatrix[this_mode][other_mode];
}
/**
* @brief Checks whether this access mode is IS mode.
*
* @return True if it is IS mode, false otherwise.
**/
inline bool isIntentionShareLock() const {
return access_mode_ == AccessModeType::kIsLockMode;
}
/**
* @brief Checks whether this access mode is IX mode.
*
* @return True if it is IX mode, false otherwise.
**/
inline bool isIntentionExclusiveLock() const {
return access_mode_ == AccessModeType::kIxLockMode;
}
/**
* @brief Checks whether this access mdoe is SIX mode.
*
* @return True if it is SIX mode, false otherwise.
**/
inline bool isShareAndIntentionExclusiveLock() const {
return access_mode_ == AccessModeType::kSixLockMode;
}
/**
* @brief Checks whether this access mode is S mode.
*
* @return True if it is S mode, false otherwise.
**/
inline bool isShareLock() const {
return access_mode_ == AccessModeType::kSLockMode;
}
/**
* @brief Checks whether this access mode is X mode.
*
* @return True if it is X mode, false otherwise.
**/
inline bool isExclusiveLock() const {
return access_mode_ == AccessModeType::kXLockMode;
}
/**
* @brief Checks whether this access mode is in
* the same level with other mode.
*
* @return True if both modes have the same level.
**/
inline bool operator==(const AccessMode &other) const {
return access_mode_ == other.access_mode_;
}
/**
* @brief Checks whether this access mode is in
* the different level with other mode.
*
* @return True if the modes have different levels.
**/
inline bool operator!=(const AccessMode &other) const {
return access_mode_ != other.access_mode_;
}
private:
typedef std::underlying_type<AccessModeType>::type
access_mode_underlying_type;
// The compatibility matrix should be N by N. kNumberLocks == N.
static constexpr std::uint64_t kNumberLocks =
static_cast<access_mode_underlying_type>(
AccessModeType::kNumAccessModeTypes);
// Compatibility matrix for checking access modes.
// True means they are compatible.
static const bool kLockCompatibilityMatrix[kNumberLocks][kNumberLocks];
// Type of access, the possible values are
// NoLock, IsLock, IxLock, SLock, SixLock, XLock
AccessModeType access_mode_;
};
/** @} */
} // namespace transaction
} // namespace quickstep
#endif // QUICKSTEP_TRANSACTION_ACCESS_MODE_HPP_