| /** |
| * 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_ |