From a4f05a0fd258cd19bb38543515a0f2e6db5f2e9e Mon Sep 17 00:00:00 2001 From: farrisli Date: Thu, 1 Apr 2021 10:28:25 +0800 Subject: [PATCH 1/2] Alter #define ... -> #pragma once; Update Lost Update and IAT Step example --- .../unified_concurrency_control/alg_dli_identify_chain.h | 6 +----- .../unified_concurrency_control/alg_dli_identify_cycle.h | 6 +----- .../deneva/unified_concurrency_control/dli_identify_util.h | 6 +----- contrib/deneva/unified_concurrency_control/operation_type.h | 5 +---- contrib/deneva/unified_concurrency_control/row_prece.h | 5 +---- .../deneva/unified_concurrency_control/txn_dli_identify.h | 6 +----- contrib/deneva/unified_concurrency_control/uni_algs.h | 5 +---- contrib/deneva/unified_concurrency_control/util.h | 6 +----- src/3ts/backend/anomaly_identify.h | 4 ++-- 9 files changed, 10 insertions(+), 39 deletions(-) diff --git a/contrib/deneva/unified_concurrency_control/alg_dli_identify_chain.h b/contrib/deneva/unified_concurrency_control/alg_dli_identify_chain.h index 88221486..81062272 100644 --- a/contrib/deneva/unified_concurrency_control/alg_dli_identify_chain.h +++ b/contrib/deneva/unified_concurrency_control/alg_dli_identify_chain.h @@ -1,6 +1,4 @@ -//#pragma once -#ifndef TTTS_DENEVA_ALG_DLI_IDENTIFY_CHAIN_H_ -#define TTTS_DENEVA_ALG_DLI_IDENTIFY_CHAIN_H_ +#pragma once #include "dli_identify_util.h" #include "row_prece.h" @@ -136,5 +134,3 @@ class AlgManager @@ -239,5 +237,3 @@ static AnomalyType IdentifyAnomalyMultiple(const std::vector& preces) } } - -#endif //TTTS_DENEVA_DLI_IDENTIFY_UTIL_H_ diff --git a/contrib/deneva/unified_concurrency_control/operation_type.h b/contrib/deneva/unified_concurrency_control/operation_type.h index f2393ab8..9479eb05 100644 --- a/contrib/deneva/unified_concurrency_control/operation_type.h +++ b/contrib/deneva/unified_concurrency_control/operation_type.h @@ -13,12 +13,9 @@ ENUM_END(OperationType) #endif #endif -#ifndef TTTS_DENEVA_OPERATION_TYPE_H_ -#define TTTS_DENEVA_OPERATION_TYPE_H_ +#pragma once namespace ttts { #define ENUM_FILE "../../../../contrib/deneva/unified_concurrency_control/operation_type.h" #include "../../../src/3ts/backend/util/extend_enum.h" } - -#endif // TTTS_DENEVA_OPERATION_TYPE_H_ diff --git a/contrib/deneva/unified_concurrency_control/row_prece.h b/contrib/deneva/unified_concurrency_control/row_prece.h index 3511b5ed..ef969c26 100644 --- a/contrib/deneva/unified_concurrency_control/row_prece.h +++ b/contrib/deneva/unified_concurrency_control/row_prece.h @@ -14,8 +14,7 @@ limitations under the License. */ -#ifndef TTTS_DENEVA_ROW_PRECE_H_ -#define TTTS_DENEVA_ROW_PRECE_H_ +#pragma once #include #include @@ -365,5 +364,3 @@ class RowManager #include @@ -27,5 +25,3 @@ class TxnManager class RowManager; template class TxnManager; } - -#endif // TTTS_DENEVA_UNTIL_H_ diff --git a/src/3ts/backend/anomaly_identify.h b/src/3ts/backend/anomaly_identify.h index 94decfac..865ab099 100644 --- a/src/3ts/backend/anomaly_identify.h +++ b/src/3ts/backend/anomaly_identify.h @@ -21,7 +21,7 @@ class Printer { public: Printer() : anomaly_map_{ {"DirtyWrite", "WAT SDA 'R0a W0a W1a R1a W1a R1a C0 C1' Wi[xm]...Wj[xm+1]"}, - {"LostUpdate", "WAT SDA 'R0a R1a W0a R0a W0a W1a C1 C0' Ri[xm]...Wj[xm+1]...Wi[xm+2]"}, + {"LostUpdate", "WAT SDA 'R0a R1a W0a R0a W0a W1a A1 C0' Ri[xm]...Wj[xm+1]...Wi[xm+2]"}, {"LostSelfUpdate", "WAT SDA 'R0a W0a R0a W1a R0a W1a C0 C1' Wi[xm]...Wj[xm+1]...Ri[xm+1]"}, {"Full-Write", "WAT SDA 'R0a W0a R1a W1a W0a C0 W1a C1' Wi[xm]...Wj[xm+1]...Wi[xm+2]"}, {"Read-WriteSkew1", "WAT DDA 'R0a W0a R0a R1b W0b W1a C0 C1' Ri[xm]...Wj[xm+1]...Wj[yn]...Wi[yn+1]"}, @@ -38,7 +38,7 @@ class Printer { {"Write-ReadSkew", "RAT DDA 'R0a W0a R1a W1b R0b R1a C0 C1' Wi[xm]...Rj[xm]...Wj[yn]...Ri[yn]"}, {"StepRAT", "RAT MDA 'R0a R0b W1a R2a R2c W0c C0 C1 C2' ...Wi[xm]...Rj[xm]..., and not include (...Wii[xm]...Wjj[xm+1]...)"}, {"WriteSkew", "IAT DDA 'R0a R0b R1a W0a R1b W1b C1 C0' Ri[xm]...Wj[xm+1]...Rj[yn]...Wi[yn+1]"}, - {"StepIAT", "IAT MDA 'R0a R0b R1c W1a W2c C1 C2 W0c C0' ...Ri[xm]...Wj[xm+1]..., and not include (...Wii[xm]...Rjj[xm]...and ...Wiii[xm]...Wjjj[xm+1]...)"} + {"StepIAT", "IAT MDA 'R0a R0b R1c W1a W2c A1 C2 W0c C0' ...Ri[xm]...Wj[xm+1]..., and not include (...Wii[xm]...Rjj[xm]...and ...Wiii[xm]...Wjjj[xm+1]...)"} }, info_map_{ {"History", "The sequence of operations that produces the data anomaly, one history contains several operations."}, {"Operation", "One operation contains 3 character, such as R0a, first character is operation type, second character is transaction id, third character is data item.\n Operation Type -> Such as R W C A(R: Read, W: Write, C: Commit, A: Aort)\n Transaction ID -> Such as 0 1 2 ...(must be a number and less than 10)\n Data Item -> Such as a b c ...(must be lowercase letter)"}, From 62b8d1053d5252257114ed019b0880cd2366996a Mon Sep 17 00:00:00 2001 From: farrisli Date: Thu, 1 Apr 2021 12:30:36 +0800 Subject: [PATCH 2/2] Support \g a, b, c --- .../alg_dli_identify_merge.h | 135 ------------------ .../operation_type.h | 5 +- .../unified_concurrency_control/uni_algs.h | 5 +- src/3ts/backend/anomaly_identify.cc | 27 ++-- src/3ts/backend/anomaly_identify.h | 36 +++-- 5 files changed, 49 insertions(+), 159 deletions(-) delete mode 100644 contrib/deneva/unified_concurrency_control/alg_dli_identify_merge.h diff --git a/contrib/deneva/unified_concurrency_control/alg_dli_identify_merge.h b/contrib/deneva/unified_concurrency_control/alg_dli_identify_merge.h deleted file mode 100644 index 57a6e35d..00000000 --- a/contrib/deneva/unified_concurrency_control/alg_dli_identify_merge.h +++ /dev/null @@ -1,135 +0,0 @@ -#pragma once - -#include "dli_identify_util.h" -#include "row_prece.h" -#include -#include - -namespace ttts { - -template -class AlgManager> -{ - public: - using Txn = TxnManager; - - bool Validate(Txn& txn) - { - txn.node_->state() = TxnNode::State::PREPARING; - - { - std::scoped_lock l(m_); - cc_txns_.emplace_back(txn.node_); - } - - Path cycle_part = DirtyCycle(*txn.node_); - - if (!cycle_part.Passable()) { - cycle_part = CyclePart_(txn); - } - - if (!cycle_part.Passable()) { - return true; - } else { - txn.cycle_ = std::make_unique(std::move(cycle_part)); - return false; - } - } - - void Commit(Txn& txn) - { - txn.node_->Commit(); - } - - void Abort(Txn& txn) - { - if (!txn.cycle_) { - // we can only identify the dirty write/read anomaly rather than avoiding it - Path cycle = DirtyCycle(*txn.node_); - txn.cycle_ = std::make_unique(std::move(cycle)); - } - if (const std::unique_ptr& cycle = txn.cycle_) { - txn.node_->Abort(true /*clear_to_txns*/); // break cycles to prevent memory leak - } else { - txn.node_->Abort(false /*clear_to_txns*/); - } - } - - void CheckConcurrencyTxnEmpty() { - std::scoped_lock l(m_); - bool is_empty = true; - for (const auto& weak_txn : cc_txns_) { - if (const auto txn = weak_txn.lock()) { - std::cerr << "** Txn Leak ** " << *txn; - is_empty = false; - } - } - // assert failed here means there is actually a cycle but we miss it - assert(is_empty); - cc_txns_.clear(); - } - - static AnomalyType IdentifyAnomaly(const std::vector& preces) - { - assert(preces.size() == 2); - const auto& p1 = preces.front(); - const auto& p2 = preces.back(); - if (std::any_of(preces.begin(), preces.end(), - [](const PreceInfo& prece) { return prece.type() == PreceType::WA || - prece.type() == PreceType::WC; })) { - return AnomalyType::WAT_1_DIRTY_WRITE; - } else if (std::any_of(preces.begin(), preces.end(), - [](const PreceInfo& prece) { return prece.type() == PreceType::RA; })) { - return AnomalyType::RAT_1_DIRTY_READ; - } else if (p1.from_txn_id() != p2.to_txn_id()) { - return IdentifyAnomalyMultiple(preces); - // [Note] When build path, later happened precedence is sorted to back, which is DIFFERENT from 3TS-DA - } else if (p1.row_id() != p2.row_id()) { - return IdentifyAnomalyDouble(p1.type(), p2.type()); - } else if (p1.to_ver_id() < p2.to_ver_id() || - (p1.to_ver_id() == p2.to_ver_id() && p1.from_ver_id() < p2.from_ver_id())) { - return IdentifyAnomalySingle(p1.type(), p2.type()); - } else { - return IdentifyAnomalySingle(p2.type(), p1.type()); - } - } - - private: - Path CyclePart_(Txn& txn) - { - // Validate failed if has a from_txn and a to_txn which are both finished but not released. - std::scoped_lock l(txn.node_->mutex()); - std::shared_ptr from_prece; - for (const auto& [_, weak_from_prece] : txn.node_->UnsafeGetFromPreces()) { - from_prece = weak_from_prece.lock(); - if (from_prece == nullptr) { - continue; - } - const auto& from_txn = from_prece->from_txn(); - if (from_txn == nullptr || from_txn->state() == TxnNode::State::ACTIVE) { - from_prece = nullptr; - continue; - } - break; - } - - std::shared_ptr to_prece; - for (const auto& [_, to_prece_tmp] : txn.node_->UnsafeGetToPreces()) { - if (to_prece_tmp->to_txn()->state() != TxnNode::State::ACTIVE) { - to_prece = to_prece_tmp; - break; - } - } - - if (from_prece && to_prece) { - return Path(std::vector{*from_prece, *to_prece}); - } - return {}; - } - - std::mutex m_; - std::vector> cc_txns_; // only for debug -}; - -} - diff --git a/contrib/deneva/unified_concurrency_control/operation_type.h b/contrib/deneva/unified_concurrency_control/operation_type.h index 9479eb05..f2393ab8 100644 --- a/contrib/deneva/unified_concurrency_control/operation_type.h +++ b/contrib/deneva/unified_concurrency_control/operation_type.h @@ -13,9 +13,12 @@ ENUM_END(OperationType) #endif #endif -#pragma once +#ifndef TTTS_DENEVA_OPERATION_TYPE_H_ +#define TTTS_DENEVA_OPERATION_TYPE_H_ namespace ttts { #define ENUM_FILE "../../../../contrib/deneva/unified_concurrency_control/operation_type.h" #include "../../../src/3ts/backend/util/extend_enum.h" } + +#endif // TTTS_DENEVA_OPERATION_TYPE_H_ diff --git a/contrib/deneva/unified_concurrency_control/uni_algs.h b/contrib/deneva/unified_concurrency_control/uni_algs.h index d88583f3..a0a326a1 100644 --- a/contrib/deneva/unified_concurrency_control/uni_algs.h +++ b/contrib/deneva/unified_concurrency_control/uni_algs.h @@ -12,9 +12,12 @@ ENUM_END(UniAlgs) #endif #endif -#pragma once +#ifndef TTTS_DENEVA_UNI_ALGS_H_ +#define TTTS_DENEVA_UNI_ALGS_H_ namespace ttts { #define ENUM_FILE "../../../../contrib/deneva/unified_concurrency_control/uni_algs.h" #include "../../../src/3ts/backend/util/extend_enum.h" } + +#endif // TTTS_DENEVA_UNI_ALGS_H_ diff --git a/src/3ts/backend/anomaly_identify.cc b/src/3ts/backend/anomaly_identify.cc index 970205cd..e2d1a2c1 100644 --- a/src/3ts/backend/anomaly_identify.cc +++ b/src/3ts/backend/anomaly_identify.cc @@ -58,16 +58,25 @@ int main() { if (index_space != text.npos) { std::string input = text.substr(index_space); Printer::TrimSpace(input); - if ("DLI_IDENTIFY_CYCLE" == input) { - printer.SetAlg(ttts::UniAlgs::UNI_DLI_IDENTIFY_CYCLE); - } else if ("DLI_IDENTIFY_CHAIN" == input) { - printer.SetAlg(ttts::UniAlgs::UNI_DLI_IDENTIFY_CHAIN); - } else if ("ALL" == input) { - printer.SetAlg(ttts::UniAlgs::ALL); - } else { + + std::vector alg_list; + std::vector alg_type_list; + Checker::split(input, alg_list, ","); + // Check the validity of the input + if (input.find("DLI_IDENTIFY_CYCLE") == input.npos && input.find("DLI_IDENTIFY_CHAIN") == input.npos) { ret = false; - Printer::Print("Unknown Algorithm"); + Printer::Print("Unknown Algorithm, please check algorithm's name"); + } + // fill and set alg_type_list + for (auto& alg : alg_list) { + if ("DLI_IDENTIFY_CYCLE" == alg) { + alg_type_list.emplace_back(ttts::UniAlgs::UNI_DLI_IDENTIFY_CYCLE); + } else if ("DLI_IDENTIFY_CHAIN" == alg) { + alg_type_list.emplace_back(ttts::UniAlgs::UNI_DLI_IDENTIFY_CHAIN); + } } + printer.SetAlgs(alg_type_list); + // print set success info if (ret) { std::cout << "Set algorithm success" << std::endl; } @@ -103,7 +112,7 @@ int main() { } else if (text.find("\\A") != text.npos || text.find("authors") != text.npos) { Printer::PrintAuthorInfo(); } else if (text.find("R") != text.npos || text.find("W") != text.npos) { - checker.ExecAnomalyIdentify(text, printer.Alg()); + checker.ExecAnomalyIdentify(text, printer.Algs()); } } return 0; diff --git a/src/3ts/backend/anomaly_identify.h b/src/3ts/backend/anomaly_identify.h index 865ab099..e7ed3f09 100644 --- a/src/3ts/backend/anomaly_identify.h +++ b/src/3ts/backend/anomaly_identify.h @@ -112,7 +112,7 @@ class Printer { static void PrintHelpInfo() { std::cout << "List of all 3TS-DAI commands:" << std::endl; std::cout << "definition (\\d) Output precise definitions of History and Anomaly, including History Operation WAT RAT IAT SDA DDA MDA, such as '\\d WAT'" << std::endl; - std::cout << "algorithm (\\g) Select the algorithm that identifies the exception, including DLI_IDENTIFY_CYCLE DLI_IDENTIFY_CHAIN ALL, such as '\\g DLI_IDENTIFY_1'" << std::endl; + std::cout << "algorithm (\\g) Select the algorithm that identifies the exception, including DLI_IDENTIFY_CYCLE DLI_IDENTIFY_CHAIN, such as '\\g DLI_IDENTIFY_CYCLE'. If you want to compare different algorithms, you can type such as '\\g DLI_IDENTIFY_CYCLE, DLI_IDENTIFY_CHAIN'" << std::endl; std::cout << "anomaly (\\a) Output history sequence of anomaly, including " << std::endl; std::cout << " WAT: Dirty Write, Lost Update, Lost Self Update, Full-Write, Read-Write Skew 1, Read-Write Skew 2, Double-Write Skew 1, Double-Write Skew 2, Full-Write Skew, Step WAT" << std::endl; std::cout << " RAT: Dirty Read, Non-Repeatable Read, Intermediate Read, Read Skew, Read Skew 2, Write-Read Skew, Step RAT" << std::endl; @@ -129,20 +129,31 @@ class Printer { str.erase(itor, str.end()); } - ttts::UniAlgs Alg() const { return alg_; }; - void SetAlg(ttts::UniAlgs alg) { alg_ = alg; }; + std::vector Algs() const { return alg_type_list_; }; + void SetAlgs(std::vector alg_type_list) { alg_type_list_ = alg_type_list; }; std::unordered_map InfoMap() const { return info_map_; }; std::unordered_map AnomalyMap() const { return anomaly_map_; }; private: - ttts::UniAlgs alg_ = ttts::UniAlgs::UNI_DLI_IDENTIFY_CYCLE; + std::vector alg_type_list_ = {ttts::UniAlgs::UNI_DLI_IDENTIFY_CYCLE}; std::unordered_map info_map_; std::unordered_map anomaly_map_; }; class Checker { public: - void ExecAnomalyIdentify(const std::string& text, ttts::UniAlgs alg_type) { + static void split(const std::string& str, std::vector& tokens, const std::string delim) { + tokens.clear(); + auto start = str.find_first_not_of(delim, 0); + auto position = str.find_first_of(delim, start); + while (position != std::string::npos || start != std::string::npos) { + tokens.emplace_back(std::move(str.substr(start, position - start))); + start = str.find_first_not_of(delim, position); + position = str.find_first_of(delim, start); + } + } + + void ExecAnomalyIdentify(const std::string& text, std::vector alg_type_list) { ttts::History history; std::istringstream is(text); @@ -152,14 +163,13 @@ class Checker { }; if ((is >> history)) { - if (alg_type == ttts::UniAlgs::UNI_DLI_IDENTIFY_CYCLE) { - get_and_print_anomaly(ttts::ConflictSerializableAlgorithm(), alg_type); - } else if (alg_type == ttts::UniAlgs::UNI_DLI_IDENTIFY_CHAIN) { - ttts::UnifiedHistoryAlgorithm alg; - get_and_print_anomaly(ttts::UnifiedHistoryAlgorithm(), alg_type); - } else if (alg_type == ttts::UniAlgs::ALL) { - get_and_print_anomaly(ttts::ConflictSerializableAlgorithm(), ttts::UniAlgs::UNI_DLI_IDENTIFY_CYCLE); - get_and_print_anomaly(ttts::UnifiedHistoryAlgorithm(), ttts::UniAlgs::UNI_DLI_IDENTIFY_CHAIN); + for (const auto& alg_type : alg_type_list) { + if (alg_type == ttts::UniAlgs::UNI_DLI_IDENTIFY_CYCLE) { + get_and_print_anomaly(ttts::ConflictSerializableAlgorithm(), alg_type); + } else if (alg_type == ttts::UniAlgs::UNI_DLI_IDENTIFY_CHAIN) { + ttts::UnifiedHistoryAlgorithm alg; + get_and_print_anomaly(ttts::UnifiedHistoryAlgorithm(), alg_type); + } } } }