diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index 99f58aeb53a..e41ab134b3c 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -352,7 +352,8 @@ void Catalog::Bootstrap() { // TODO: change pg_proc to per database ProcCatalog::GetInstance(txn); - if (settings::SettingsManager::GetBool(settings::SettingId::brain)) { + if (settings::SettingsManager::GetInstance().GetBool( + settings::SettingId::brain)) { QueryHistoryCatalog::GetInstance(txn); } @@ -958,7 +959,8 @@ ResultType Catalog::AddUniqueConstraint(concurrency::TransactionContext *txn, ->GetSchema(); // Create index - std::stringstream index_name(table_object->GetTableName()); + std::stringstream index_name; + index_name << table_object->GetTableName(); for (auto column_id : column_ids) index_name << "_" + schema->GetColumn(column_id).GetName(); index_name << "_UNIQ"; @@ -1033,7 +1035,8 @@ ResultType Catalog::AddForeignKeyConstraint(concurrency::TransactionContext *txn ->GetTableCatalogEntry(txn, src_table_oid); auto src_schema = src_table->GetSchema(); - std::stringstream index_name(src_table_object->GetTableName()); + std::stringstream index_name; + index_name << src_table_object->GetTableName(); for (auto col_id : src_col_ids) index_name << "_" << src_schema->GetColumn(col_id).GetName(); index_name << "_fkey"; diff --git a/src/catalog/settings_catalog.cpp b/src/catalog/settings_catalog.cpp index de483314d4b..a62dab410ed 100644 --- a/src/catalog/settings_catalog.cpp +++ b/src/catalog/settings_catalog.cpp @@ -21,6 +21,99 @@ namespace peloton { namespace catalog { +SettingsCatalogEntry::SettingsCatalogEntry(executor::LogicalTile *tile, + int tuple_id) + : name_(tile->GetValue(tuple_id, + static_cast(SettingsCatalog::ColumnId::NAME)) + .ToString()), + value_type_(StringToTypeId( + tile->GetValue(tuple_id, static_cast( + SettingsCatalog::ColumnId::VALUE_TYPE)) + .ToString())), + desc_(tile->GetValue( + tuple_id, + static_cast(SettingsCatalog::ColumnId::DESCRIPTION)) + .ToString()), + is_mutable_( + tile->GetValue(tuple_id, static_cast( + SettingsCatalog::ColumnId::IS_MUTABLE)) + .GetAs()), + is_persistent_( + tile->GetValue( + tuple_id, + static_cast(SettingsCatalog::ColumnId::IS_PERSISTENT)) + .GetAs()) { + switch (value_type_) { + case type::TypeId::INTEGER: { + value_ = type::ValueFactory::GetIntegerValue(std::stoi( + tile->GetValue(tuple_id, + static_cast(SettingsCatalog::ColumnId::VALUE)) + .ToString())); + default_value_ = type::ValueFactory::GetIntegerValue(std::stoi( + tile->GetValue( + tuple_id, + static_cast(SettingsCatalog::ColumnId::DEFAULT_VALUE)) + .ToString())); + min_value_ = type::ValueFactory::GetIntegerValue(std::stoi( + tile->GetValue(tuple_id, + static_cast(SettingsCatalog::ColumnId::MIN_VALUE)) + .ToString())); + max_value_ = type::ValueFactory::GetIntegerValue(std::stoi( + tile->GetValue(tuple_id, + static_cast(SettingsCatalog::ColumnId::MAX_VALUE)) + .ToString())); + break; + } + case type::TypeId::DECIMAL: { + value_ = type::ValueFactory::GetDecimalValue(std::stof( + tile->GetValue(tuple_id, + static_cast(SettingsCatalog::ColumnId::VALUE)) + .ToString())); + default_value_ = type::ValueFactory::GetDecimalValue(std::stof( + tile->GetValue( + tuple_id, + static_cast(SettingsCatalog::ColumnId::DEFAULT_VALUE)) + .ToString())); + min_value_ = type::ValueFactory::GetDecimalValue(std::stof( + tile->GetValue(tuple_id, + static_cast(SettingsCatalog::ColumnId::MIN_VALUE)) + .ToString())); + max_value_ = type::ValueFactory::GetDecimalValue(std::stof( + tile->GetValue(tuple_id, + static_cast(SettingsCatalog::ColumnId::MAX_VALUE)) + .ToString())); + break; + } + case type::TypeId::BOOLEAN: { + value_ = type::ValueFactory::GetBooleanValue( + (tile->GetValue(tuple_id, + static_cast(SettingsCatalog::ColumnId::VALUE)) + .ToString() == "true") + ? true + : false); + default_value_ = type::ValueFactory::GetBooleanValue( + (tile->GetValue( + tuple_id, + static_cast(SettingsCatalog::ColumnId::DEFAULT_VALUE)) + .ToString() == "true") + ? true + : false); + break; + } + case type::TypeId::VARCHAR: { + value_ = tile->GetValue( + tuple_id, static_cast(SettingsCatalog::ColumnId::VALUE)); + default_value_ = tile->GetValue( + tuple_id, static_cast(SettingsCatalog::ColumnId::DEFAULT_VALUE)); + break; + } + default: + LOG_ERROR("Unsupported type for setting value: %s", + TypeIdToString(value_type_).c_str()); + PELOTON_ASSERT(false); + } +} + SettingsCatalog &SettingsCatalog::GetInstance( concurrency::TransactionContext *txn) { static SettingsCatalog settings_catalog{txn}; @@ -102,9 +195,54 @@ bool SettingsCatalog::DeleteSetting(concurrency::TransactionContext *txn, return DeleteWithIndexScan(txn, index_offset, values); } -std::string SettingsCatalog::GetSettingValue(concurrency::TransactionContext *txn, - const std::string &name) { - std::vector column_ids({static_cast(ColumnId::VALUE)}); +/** @brief Update a setting catalog entry corresponding to a name + * in the pg_settings. + * @param txn TransactionContext for getting the setting. + * @param name name of the setting. + * @param value value for the updating. + * @return setting catalog entry. + */ +bool SettingsCatalog::UpdateSettingValue(concurrency::TransactionContext *txn, + const std::string &name, + const std::string &value, + bool set_default) { + std::vector update_columns( + {static_cast(ColumnId::VALUE)}); // value + oid_t index_offset = + static_cast(IndexId::SECONDARY_KEY_0); // Index of name + // values to execute index scan + std::vector scan_values; + scan_values.push_back(type::ValueFactory::GetVarcharValue(name).Copy()); + // values to update + std::vector update_values; + update_values.push_back(type::ValueFactory::GetVarcharValue(value).Copy()); + + if (set_default) { + update_columns.push_back(static_cast(ColumnId::DEFAULT_VALUE)); + update_values.push_back(type::ValueFactory::GetVarcharValue(value).Copy()); + } + + return UpdateWithIndexScan(txn, + index_offset, + scan_values, + update_columns, + update_values); +} + +/** @brief Get a setting catalog entry corresponding to a name + * from the pg_settings. + * @param txn TransactionContext for getting the setting. + * @param name name of the setting. + * @return setting catalog entry. + */ +std::shared_ptr +SettingsCatalog::GetSettingsCatalogEntry(concurrency::TransactionContext *txn, + const std::string &name) { + if (txn == nullptr) { + throw CatalogException("Transaction is invalid!"); + } + + std::vector column_ids(all_column_ids_); oid_t index_offset = static_cast(IndexId::SECONDARY_KEY_0); std::vector values; values.push_back(type::ValueFactory::GetVarcharValue(name, nullptr).Copy()); @@ -115,39 +253,44 @@ std::string SettingsCatalog::GetSettingValue(concurrency::TransactionContext *tx index_offset, values); - std::string config_value = ""; PELOTON_ASSERT(result_tiles->size() <= 1); if (result_tiles->size() != 0) { PELOTON_ASSERT((*result_tiles)[0]->GetTupleCount() <= 1); if ((*result_tiles)[0]->GetTupleCount() != 0) { - config_value = (*result_tiles)[0]->GetValue(0, 0).ToString(); + return std::make_shared((*result_tiles)[0].get()); } } - return config_value; + + return nullptr; } -std::string SettingsCatalog::GetDefaultValue(concurrency::TransactionContext *txn, - const std::string &name) { - std::vector column_ids({static_cast(ColumnId::VALUE)}); - oid_t index_offset = static_cast(IndexId::SECONDARY_KEY_0); - std::vector values; - values.push_back(type::ValueFactory::GetVarcharValue(name, nullptr).Copy()); +/** @brief Get all setting catalog entries from the pg_settings. + * @param txn TransactionContext for getting the settings. + * @return unordered_map containing a name -> setting catalog + * entry mapping. + */ +std::unordered_map> +SettingsCatalog::GetSettingsCatalogEntries(concurrency::TransactionContext *txn) { + if (txn == nullptr) { + throw CatalogException("Transaction is invalid!"); + } - auto result_tiles = - GetResultWithIndexScan(txn, - column_ids, - index_offset, - values); + std::vector column_ids(all_column_ids_); - std::string config_value = ""; - PELOTON_ASSERT(result_tiles->size() <= 1); - if (result_tiles->size() != 0) { - PELOTON_ASSERT((*result_tiles)[0]->GetTupleCount() <= 1); - if ((*result_tiles)[0]->GetTupleCount() != 0) { - config_value = (*result_tiles)[0]->GetValue(0, 0).ToString(); + auto result_tiles = this->GetResultWithSeqScan(txn, nullptr, column_ids); + + std::unordered_map> + setting_entries; + for (auto &tile : (*result_tiles)) { + for (auto tuple_id : *tile) { + auto setting_entry = + std::make_shared(tile.get(), tuple_id); + setting_entries.insert( + std::make_pair(setting_entry->GetName(), setting_entry)); } } - return config_value; + + return setting_entries; } } // namespace catalog diff --git a/src/codegen/code_context.cpp b/src/codegen/code_context.cpp index 14731e4fdc1..41eea600c4a 100644 --- a/src/codegen/code_context.cpp +++ b/src/codegen/code_context.cpp @@ -311,8 +311,8 @@ void CodeContext::Compile() { // make sure the code is verified if (!is_verified_) Verify(); - // Print some IR stats - if (settings::SettingsManager::GetBool(settings::SettingId::print_ir_stats)) { + if (settings::SettingsManager::GetInstance().GetBool( + settings::SettingId::print_ir_stats)) { char name[] = "inst count"; InstructionCounts inst_count(*name); inst_count.runOnModule(GetModule()); @@ -329,7 +329,8 @@ void CodeContext::Compile() { // Log the module LOG_TRACE("%s\n", GetIR().c_str()); - if (settings::SettingsManager::GetBool(settings::SettingId::dump_ir)) { +if (settings::SettingsManager::GetInstance().GetBool( + settings::SettingId::dump_ir)) { LOG_DEBUG("%s\n", GetIR().c_str()); } } @@ -407,4 +408,4 @@ std::string CodeContext::GetIR() const { } } // namespace codegen -} // namespace peloton \ No newline at end of file +} // namespace peloton diff --git a/src/codegen/operator/block_nested_loop_join_translator.cpp b/src/codegen/operator/block_nested_loop_join_translator.cpp index a61cbb60da1..740b2d8c092 100644 --- a/src/codegen/operator/block_nested_loop_join_translator.cpp +++ b/src/codegen/operator/block_nested_loop_join_translator.cpp @@ -104,7 +104,7 @@ BlockNestedLoopJoinTranslator::BlockNestedLoopJoinTranslator( buffer_ = BufferAccessor(codegen, left_input_desc); // Determine the number of rows to buffer before flushing it through the join - auto max_buffer_size = settings::SettingsManager::GetDouble( + auto max_buffer_size = settings::SettingsManager::GetInstance().GetDouble( settings::SettingId::bnlj_buffer_size); auto row_size = buffer_.GetTupleSize(); max_buf_rows_ = diff --git a/src/codegen/pipeline.cpp b/src/codegen/pipeline.cpp index 47b0d509b30..8c0b3ee1d53 100644 --- a/src/codegen/pipeline.cpp +++ b/src/codegen/pipeline.cpp @@ -259,7 +259,7 @@ void Pipeline::MarkSource(OperatorTranslator *translator, PELOTON_ASSERT(translator == pipeline_.back()); // Check parallel execution settings - bool parallel_exec_disabled = !settings::SettingsManager::GetBool( + bool parallel_exec_disabled = !settings::SettingsManager::GetInstance().GetBool( settings::SettingId::parallel_execution); // Check if the consumer supports parallel execution @@ -630,4 +630,4 @@ std::string Pipeline::GetInfo() const { } } // namespace codegen -} // namespace peloton \ No newline at end of file +} // namespace peloton diff --git a/src/codegen/query.cpp b/src/codegen/query.cpp index c69601b3b7f..5f9625c15cb 100644 --- a/src/codegen/query.cpp +++ b/src/codegen/query.cpp @@ -47,7 +47,7 @@ void Query::Execute(executor::ExecutorContext &executor_context, func_args->executor_context = &executor_context; func_args->consumer_arg = consumer.GetConsumerState(); - bool force_interpreter = settings::SettingsManager::GetBool( + bool force_interpreter = settings::SettingsManager::GetInstance().GetBool( settings::SettingId::codegen_interpreter); if (is_compiled_ && !force_interpreter) { diff --git a/src/common/init.cpp b/src/common/init.cpp index c8b87133211..b9c1d607147 100644 --- a/src/common/init.cpp +++ b/src/common/init.cpp @@ -31,7 +31,9 @@ namespace peloton { ThreadPool thread_pool; void PelotonInit::Initialize() { - CONNECTION_THREAD_COUNT = settings::SettingsManager::GetInt( + auto &settings_manager = settings::SettingsManager::GetInstance(); + + CONNECTION_THREAD_COUNT = settings_manager.GetInt( settings::SettingId::connection_thread_count); LOGGING_THREAD_COUNT = 1; GC_THREAD_COUNT = 1; @@ -44,7 +46,7 @@ void PelotonInit::Initialize() { threadpool::MonoQueuePool::GetInstance().Startup(); // start indextuner thread pool - if (settings::SettingsManager::GetBool(settings::SettingId::brain)) { + if (settings_manager.GetBool(settings::SettingId::brain)) { threadpool::MonoQueuePool::GetBrainInstance().Startup(); } @@ -59,11 +61,12 @@ void PelotonInit::Initialize() { concurrency::EpochManagerFactory::GetInstance().StartEpoch(); // start GC. - gc::GCManagerFactory::Configure(settings::SettingsManager::GetInt(settings::SettingId::gc_num_threads)); + gc::GCManagerFactory::Configure( + settings_manager.GetInt(settings::SettingId::gc_num_threads)); gc::GCManagerFactory::GetInstance().StartGC(); // start index tuner - if (settings::SettingsManager::GetBool(settings::SettingId::index_tuner)) { + if (settings_manager.GetBool(settings::SettingId::index_tuner)) { // Set the default visibility flag for all indexes to false index::IndexMetadata::SetDefaultVisibleFlag(false); auto &index_tuner = tuning::IndexTuner::GetInstance(); @@ -71,7 +74,7 @@ void PelotonInit::Initialize() { } // start layout tuner - if (settings::SettingsManager::GetBool(settings::SettingId::layout_tuner)) { + if (settings_manager.GetBool(settings::SettingId::layout_tuner)) { auto &layout_tuner = tuning::LayoutTuner::GetInstance(); layout_tuner.Start(); } @@ -79,7 +82,7 @@ void PelotonInit::Initialize() { // Initialize catalog auto pg_catalog = catalog::Catalog::GetInstance(); pg_catalog->Bootstrap(); // Additional catalogs - settings::SettingsManager::GetInstance().InitializeCatalog(); + settings_manager.InitializeCatalog(); // begin a transaction auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); @@ -96,14 +99,16 @@ void PelotonInit::Initialize() { } void PelotonInit::Shutdown() { + auto &settings_manager = settings::SettingsManager::GetInstance(); + // shut down index tuner - if (settings::SettingsManager::GetBool(settings::SettingId::index_tuner)) { + if (settings_manager.GetBool(settings::SettingId::index_tuner)) { auto &index_tuner = tuning::IndexTuner::GetInstance(); index_tuner.Stop(); } // shut down layout tuner - if (settings::SettingsManager::GetBool(settings::SettingId::layout_tuner)) { + if (settings_manager.GetBool(settings::SettingId::layout_tuner)) { auto &layout_tuner = tuning::LayoutTuner::GetInstance(); layout_tuner.Stop(); } @@ -121,7 +126,7 @@ void PelotonInit::Shutdown() { threadpool::MonoQueuePool::GetInstance().Shutdown(); // stop indextuner thread pool - if (settings::SettingsManager::GetBool(settings::SettingId::brain)) { + if (settings_manager.GetBool(settings::SettingId::brain)) { threadpool::MonoQueuePool::GetBrainInstance().Shutdown(); } diff --git a/src/concurrency/transaction_manager.cpp b/src/concurrency/transaction_manager.cpp index d3171213e32..f32c608e670 100644 --- a/src/concurrency/transaction_manager.cpp +++ b/src/concurrency/transaction_manager.cpp @@ -78,7 +78,8 @@ void TransactionManager::EndTransaction(TransactionContext *current_txn) { // log RWSet and result stats const auto &stats_type = static_cast( - settings::SettingsManager::GetInt(settings::SettingId::stats_mode)); + settings::SettingsManager::GetInstance().GetInt( + settings::SettingId::stats_mode)); // update stats if (stats_type != StatsType::INVALID) { @@ -251,8 +252,9 @@ VisibilityType TransactionManager::IsVisible( void TransactionManager::RecordTransactionStats( const TransactionContext *const current_txn) const { - PELOTON_ASSERT(static_cast(settings::SettingsManager::GetInt( - settings::SettingId::stats_mode)) != StatsType::INVALID); + PELOTON_ASSERT(static_cast( + settings::SettingsManager::GetInstance().GetInt( + settings::SettingId::stats_mode)) != StatsType::INVALID); auto stats_context = stats::BackendStatsContext::GetInstance(); const auto &rw_set = current_txn->GetReadWriteSet(); diff --git a/src/executor/plan_executor.cpp b/src/executor/plan_executor.cpp index a945c46bc59..0d2deaa0e88 100644 --- a/src/executor/plan_executor.cpp +++ b/src/executor/plan_executor.cpp @@ -159,7 +159,7 @@ void PlanExecutor::ExecutePlan( LOG_TRACE("PlanExecutor Start (Txn ID=%" PRId64 ")", txn->GetTransactionId()); bool codegen_enabled = - settings::SettingsManager::GetBool(settings::SettingId::codegen); + settings::SettingsManager::GetInstance().GetBool(settings::SettingId::codegen); try { if (codegen_enabled && codegen::QueryCompiler::IsSupported(*plan)) { diff --git a/src/gc/transaction_level_gc_manager.cpp b/src/gc/transaction_level_gc_manager.cpp index e6630aa6cf6..7230498b2c5 100644 --- a/src/gc/transaction_level_gc_manager.cpp +++ b/src/gc/transaction_level_gc_manager.cpp @@ -130,7 +130,8 @@ int TransactionLevelGCManager::Unlink(const int &thread_id, } // Log the query into query_history_catalog - if (settings::SettingsManager::GetBool(settings::SettingId::brain)) { + if (settings::SettingsManager::GetInstance().GetBool( + settings::SettingId::brain)) { std::vector query_strings = txn_ctx->GetQueryStrings(); if (query_strings.size() != 0) { uint64_t timestamp = txn_ctx->GetTimestamp(); diff --git a/src/include/catalog/settings_catalog.h b/src/include/catalog/settings_catalog.h index 3441658ef0a..e986769d2c1 100644 --- a/src/include/catalog/settings_catalog.h +++ b/src/include/catalog/settings_catalog.h @@ -17,12 +17,46 @@ namespace peloton { namespace catalog { +//===----------------------------------------------------------------------===// +// In-memory representation of a row from the pg_settings table. +//===----------------------------------------------------------------------===// +class SettingsCatalogEntry { + public: + SettingsCatalogEntry(executor::LogicalTile *tile, int tuple_id = 0); + + // Accessors + inline const std::string &GetName() { return name_; } + inline type::Value &GetValue() { return value_; } + inline type::TypeId GetValueType() { return value_type_; } + inline const std::string &GetDescription() { return desc_; } + inline type::Value &GetDefaultValue() { return default_value_; } + inline type::Value &GetMinValue() { return min_value_; } + inline type::Value &GetMaxValue() { return max_value_; } + inline bool IsMutable() { return is_mutable_; } + inline bool IsPersistent() { return is_persistent_; } + + private: + // The fields of 'pg_settings' table + std::string name_; + type::Value value_; + type::TypeId value_type_; + std::string desc_; + type::Value default_value_; + type::Value min_value_; + type::Value max_value_; + bool is_mutable_, is_persistent_; +}; + +//===----------------------------------------------------------------------===// +// The pg_settings catalog table. +//===----------------------------------------------------------------------===// class SettingsCatalog : public AbstractCatalog { public: ~SettingsCatalog(); // Global Singleton - static SettingsCatalog &GetInstance(concurrency::TransactionContext *txn = nullptr); + static SettingsCatalog &GetInstance( + concurrency::TransactionContext *txn = nullptr); //===--------------------------------------------------------------------===// // write Related API @@ -42,14 +76,19 @@ class SettingsCatalog : public AbstractCatalog { bool DeleteSetting(concurrency::TransactionContext *txn, const std::string &name); + bool UpdateSettingValue(concurrency::TransactionContext *txn, + const std::string &name, const std::string &value, + bool set_default); + //===--------------------------------------------------------------------===// // Read-only Related API //===--------------------------------------------------------------------===// - std::string GetSettingValue(concurrency::TransactionContext *txn, - const std::string &name); + std::shared_ptr + GetSettingsCatalogEntry(concurrency::TransactionContext *txn, + const std::string &name); - std::string GetDefaultValue(concurrency::TransactionContext *txn, - const std::string &name); + std::unordered_map> + GetSettingsCatalogEntries(concurrency::TransactionContext *txn); enum class ColumnId { NAME = 0, @@ -63,6 +102,7 @@ class SettingsCatalog : public AbstractCatalog { IS_PERSISTENT = 8, // Add new columns here in creation order }; + std::vector all_column_ids_ = {0, 1, 2, 3, 4, 5, 6, 7, 8}; private: SettingsCatalog(concurrency::TransactionContext *txn); diff --git a/src/include/optimizer/optimizer_metadata.h b/src/include/optimizer/optimizer_metadata.h index 8606d8a3dae..e6839f51fdd 100644 --- a/src/include/optimizer/optimizer_metadata.h +++ b/src/include/optimizer/optimizer_metadata.h @@ -31,7 +31,7 @@ class RuleSet; class OptimizerMetadata { public: OptimizerMetadata() - : timeout_limit(settings::SettingsManager::GetInt( + : timeout_limit(settings::SettingsManager::GetInstance().GetInt( settings::SettingId::task_execution_timeout)), timer(Timer()) {} diff --git a/src/include/settings/settings_manager.h b/src/include/settings/settings_manager.h index 9081ac0217e..bc02f2047f2 100644 --- a/src/include/settings/settings_manager.h +++ b/src/include/settings/settings_manager.h @@ -10,7 +10,6 @@ // //===----------------------------------------------------------------------===// - #pragma once #include @@ -18,6 +17,7 @@ #include "type/value.h" #include "common/exception.h" #include "common/printable.h" +#include "concurrency/transaction_context.h" #include "settings/setting_id.h" namespace peloton { @@ -28,26 +28,48 @@ namespace settings { // It stores information in an internal map as well as catalog pg_settings class SettingsManager : public Printable { public: - static int32_t GetInt(SettingId id); - static double GetDouble(SettingId id); - static bool GetBool(SettingId id); - static std::string GetString(SettingId id); - - static void SetInt(SettingId id, int32_t value); - static void SetBool(SettingId id, bool value); - static void SetString(SettingId id, const std::string &value); static SettingsManager &GetInstance(); + // Getter functions for setting value. + int32_t GetInt(SettingId id) const; + double GetDouble(SettingId id) const; + bool GetBool(SettingId id) const; + std::string GetString(SettingId id) const; + type::Value GetValue(SettingId id) const; + + // Setter functions to update internal setting value. + // These can be called without txn before calling InitializeCatalog(). + // If set_default is true, then set default_value in addition to value. + void SetInt(SettingId id, int32_t value, bool set_default = false, + concurrency::TransactionContext *txn = nullptr); + void SetDouble(SettingId id, double value, bool set_default = false, + concurrency::TransactionContext *txn = nullptr); + void SetBool(SettingId id, bool value, bool set_default = false, + concurrency::TransactionContext *txn = nullptr); + void SetString(SettingId id, const std::string &value, + bool set_default = false, + concurrency::TransactionContext *txn = nullptr); + void SetValue(SettingId id, const type::Value &value, + bool set_default = false, + concurrency::TransactionContext *txn = nullptr); + + // Reset a setting value to a default value + // This can be called without txn before calling InitializeCatalog(). + // If set_default is true, then set default_value in addition to value. + void ResetValue(SettingId id, + concurrency::TransactionContext *txn = nullptr); + // Call this method in Catalog->Bootstrap // to store information into pg_settings void InitializeCatalog(); + void UpdateSettingListFromCatalog(concurrency::TransactionContext *txn); + const std::string GetInfo() const; void ShowInfo(); private: - // local information storage // name, value, description, default_value, is_mutable, is_persistent struct Param { @@ -55,20 +77,29 @@ class SettingsManager : public Printable { type::Value value; std::string desc; type::Value default_value; + type::Value min_value; + type::Value max_value; bool is_mutable, is_persistent; - Param(std::string name, const type::Value &value, - std::string desc, const type::Value &default_value, - bool is_mutable, bool is_persistent) - : name(name), value(value), desc(desc), + Param(std::string name, const type::Value &value, std::string desc, + const type::Value &default_value, type::Value min_value, + type::Value max_value, bool is_mutable, bool is_persistent) + : name(name), + value(value), + desc(desc), default_value(default_value), - is_mutable(is_mutable), is_persistent(is_persistent) {} + min_value(min_value), + max_value(max_value), + is_mutable(is_mutable), + is_persistent(is_persistent) {} }; // internal map struct EnumClassHash { - template std::size_t operator()(T t) - const { return static_cast(t); } + template + std::size_t operator()(T t) const { + return static_cast(t); + } }; std::unordered_map settings_; @@ -79,18 +110,15 @@ class SettingsManager : public Printable { SettingsManager(); void DefineSetting(SettingId id, const std::string &name, - const type::Value &value, - const std::string &description, + const type::Value &value, const std::string &description, const type::Value &default_value, - const type::Value &min_value, - const type::Value &max_value, + const type::Value &min_value, const type::Value &max_value, bool is_mutable, bool is_persistent); - type::Value GetValue(SettingId id); - - void SetValue(SettingId id, const type::Value &value); + bool InsertCatalog(const Param ¶m, concurrency::TransactionContext *txn); - bool InsertIntoCatalog(const Param ¶m); + bool UpdateCatalog(const std::string &name, const type::Value &value, + bool set_default, concurrency::TransactionContext *txn); }; } // namespace settings diff --git a/src/include/threadpool/mono_queue_pool.h b/src/include/threadpool/mono_queue_pool.h index fbee1985f22..f7ad98d82c0 100644 --- a/src/include/threadpool/mono_queue_pool.h +++ b/src/include/threadpool/mono_queue_pool.h @@ -87,9 +87,10 @@ inline void MonoQueuePool::SubmitTask(const F &func) { } inline MonoQueuePool &MonoQueuePool::GetInstance() { - int32_t task_queue_size = settings::SettingsManager::GetInt( + auto &settings_manager = settings::SettingsManager::GetInstance(); + int32_t task_queue_size = settings_manager.GetInt( settings::SettingId::monoqueue_task_queue_size); - int32_t worker_pool_size = settings::SettingsManager::GetInt( + int32_t worker_pool_size = settings_manager.GetInt( settings::SettingId::monoqueue_worker_pool_size); PELOTON_ASSERT(task_queue_size > 0); @@ -104,9 +105,10 @@ inline MonoQueuePool &MonoQueuePool::GetInstance() { } inline MonoQueuePool &MonoQueuePool::GetBrainInstance() { - int32_t task_queue_size = settings::SettingsManager::GetInt( + auto &settings_manager = settings::SettingsManager::GetInstance(); + int32_t task_queue_size = settings_manager.GetInt( settings::SettingId::brain_task_queue_size); - int32_t worker_pool_size = settings::SettingsManager::GetInt( + int32_t worker_pool_size = settings_manager.GetInt( settings::SettingId::brain_worker_pool_size); PELOTON_ASSERT(task_queue_size > 0); @@ -121,9 +123,10 @@ inline MonoQueuePool &MonoQueuePool::GetBrainInstance() { } inline MonoQueuePool &MonoQueuePool::GetExecutionInstance() { - int32_t task_queue_size = settings::SettingsManager::GetInt( + auto &settings_manager = settings::SettingsManager::GetInstance(); + int32_t task_queue_size = settings_manager.GetInt( settings::SettingId::monoqueue_task_queue_size); - int32_t worker_pool_size = settings::SettingsManager::GetInt( + int32_t worker_pool_size = settings_manager.GetInt( settings::SettingId::monoqueue_worker_pool_size); PELOTON_ASSERT(task_queue_size > 0); diff --git a/src/index/art_index.cpp b/src/index/art_index.cpp index 18de5d02393..fc0f3d6e700 100644 --- a/src/index/art_index.cpp +++ b/src/index/art_index.cpp @@ -65,7 +65,7 @@ bool ArtIndex::InsertEntry(const storage::Tuple *key, ItemPointer *value) { auto thread_info = container_.getThreadInfo(); container_.insert(tree_key, reinterpret_cast(value), thread_info); - if (static_cast(settings::SettingsManager::GetInt( + if (static_cast(settings::SettingsManager::GetInstance().GetInt( settings::SettingId::stats_mode)) != StatsType::INVALID) { stats::BackendStatsContext::GetInstance()->IncrementIndexInserts( GetMetadata()); @@ -90,7 +90,7 @@ bool ArtIndex::DeleteEntry(const storage::Tuple *key, ItemPointer *value) { if (removed) { // Update stats DecreaseNumberOfTuplesBy(1); - if (static_cast(settings::SettingsManager::GetInt( + if (static_cast(settings::SettingsManager::GetInstance().GetInt( settings::SettingId::stats_mode)) != StatsType::INVALID) { stats::BackendStatsContext::GetInstance()->IncrementIndexDeletes( 1, GetMetadata()); @@ -114,7 +114,7 @@ bool ArtIndex::CondInsertEntry(const storage::Tuple *key, ItemPointer *value, if (inserted) { // Update stats IncreaseNumberOfTuplesBy(1); - if (static_cast(settings::SettingsManager::GetInt( + if (static_cast(settings::SettingsManager::GetInstance().GetInt( settings::SettingId::stats_mode)) != StatsType::INVALID) { stats::BackendStatsContext::GetInstance()->IncrementIndexInserts( GetMetadata()); @@ -153,7 +153,7 @@ void ArtIndex::Scan( } // Update stats - if (static_cast(settings::SettingsManager::GetInt( + if (static_cast(settings::SettingsManager::GetInstance().GetInt( settings::SettingId::stats_mode)) != StatsType::INVALID) { stats::BackendStatsContext::GetInstance()->IncrementIndexReads( result.size(), GetMetadata()); @@ -225,7 +225,7 @@ void ArtIndex::ScanRange(const art::Key &start, const art::Key &end, } // Update stats - if (static_cast(settings::SettingsManager::GetInt( + if (static_cast(settings::SettingsManager::GetInstance().GetInt( settings::SettingId::stats_mode)) != StatsType::INVALID) { stats::BackendStatsContext::GetInstance()->IncrementIndexReads( result.size(), GetMetadata()); @@ -376,4 +376,4 @@ void ArtIndex::KeyConstructor::ConstructMinMaxKey(art::Key &min_key, } } // namespace index -} // namespace peloton \ No newline at end of file +} // namespace peloton diff --git a/src/index/bwtree_index.cpp b/src/index/bwtree_index.cpp index 74094843ef8..45fd8d631fd 100755 --- a/src/index/bwtree_index.cpp +++ b/src/index/bwtree_index.cpp @@ -60,7 +60,8 @@ bool BWTREE_INDEX_TYPE::InsertEntry(const storage::Tuple *key, ret = container.Insert(index_key, value, false); } - if (static_cast(settings::SettingsManager::GetInt(settings::SettingId::stats_mode)) != StatsType::INVALID) { + if (static_cast(settings::SettingsManager::GetInstance().GetInt( + settings::SettingId::stats_mode)) != StatsType::INVALID) { stats::BackendStatsContext::GetInstance()->IncrementIndexInserts(metadata); } @@ -90,7 +91,8 @@ bool BWTREE_INDEX_TYPE::DeleteEntry(const storage::Tuple *key, // it is unnecessary for us to allocate memory bool ret = container.Delete(index_key, value); - if (static_cast(settings::SettingsManager::GetInt(settings::SettingId::stats_mode)) != StatsType::INVALID) { + if (static_cast(settings::SettingsManager::GetInstance().GetInt( + settings::SettingId::stats_mode)) != StatsType::INVALID) { stats::BackendStatsContext::GetInstance()->IncrementIndexDeletes( delete_count, metadata); } @@ -126,7 +128,8 @@ bool BWTREE_INDEX_TYPE::CondInsertEntry( assert(ret == false); } - if (static_cast(settings::SettingsManager::GetInt(settings::SettingId::stats_mode)) != StatsType::INVALID) { + if (static_cast(settings::SettingsManager::GetInstance().GetInt( + settings::SettingId::stats_mode)) != StatsType::INVALID) { stats::BackendStatsContext::GetInstance()->IncrementIndexInserts(metadata); } @@ -200,7 +203,8 @@ void BWTREE_INDEX_TYPE::Scan( } } // if is full scan - if (static_cast(settings::SettingsManager::GetInt(settings::SettingId::stats_mode)) != StatsType::INVALID) { + if (static_cast(settings::SettingsManager::GetInstance(). + GetInt(settings::SettingId::stats_mode)) != StatsType::INVALID) { stats::BackendStatsContext::GetInstance()->IncrementIndexReads( result.size(), metadata); } @@ -267,7 +271,8 @@ void BWTREE_INDEX_TYPE::ScanAllKeys(std::vector &result) { it++; } - if (static_cast(settings::SettingsManager::GetInt(settings::SettingId::stats_mode)) != StatsType::INVALID) { + if (static_cast(settings::SettingsManager::GetInstance().GetInt( + settings::SettingId::stats_mode)) != StatsType::INVALID) { stats::BackendStatsContext::GetInstance()->IncrementIndexReads( result.size(), metadata); } @@ -283,7 +288,8 @@ void BWTREE_INDEX_TYPE::ScanKey(const storage::Tuple *key, // This function in BwTree fills a given vector container.GetValue(index_key, result); - if (static_cast(settings::SettingsManager::GetInt(settings::SettingId::stats_mode)) != StatsType::INVALID) { + if (static_cast(settings::SettingsManager::GetInstance().GetInt( + settings::SettingId::stats_mode)) != StatsType::INVALID) { stats::BackendStatsContext::GetInstance()->IncrementIndexReads( result.size(), metadata); } diff --git a/src/main/peloton/peloton.cpp b/src/main/peloton/peloton.cpp index 8c5e0b204c6..67d61fc13da 100644 --- a/src/main/peloton/peloton.cpp +++ b/src/main/peloton/peloton.cpp @@ -81,10 +81,10 @@ int main(int argc, char *argv[]) { } try { + // Load build-in settings + auto &settings = peloton::settings::SettingsManager::GetInstance(); // Print settings - if (peloton::settings::SettingsManager::GetBool( - peloton::settings::SettingId::display_settings)) { - auto &settings = peloton::settings::SettingsManager::GetInstance(); + if (settings.GetBool(peloton::settings::SettingId::display_settings)) { settings.ShowInfo(); } } catch (peloton::SettingsException &exception) { @@ -93,7 +93,7 @@ int main(int argc, char *argv[]) { } int exit_code = 0; - if (peloton::settings::SettingsManager::GetBool( + if (peloton::settings::SettingsManager::GetInstance().GetBool( peloton::settings::SettingId::brain)) exit_code = RunPelotonBrain(); else diff --git a/src/network/peloton_server.cpp b/src/network/peloton_server.cpp index b667a42e932..2f0f32610f8 100644 --- a/src/network/peloton_server.cpp +++ b/src/network/peloton_server.cpp @@ -83,16 +83,18 @@ unsigned long PelotonServer::SSLIdFunction(void) { } void PelotonServer::LoadSSLFileSettings() { - private_key_file_ = DATA_DIR + settings::SettingsManager::GetString( + auto &settings_manager = settings::SettingsManager::GetInstance(); + private_key_file_ = DATA_DIR + settings_manager.GetString( settings::SettingId::private_key_file); - certificate_file_ = DATA_DIR + settings::SettingsManager::GetString( + certificate_file_ = DATA_DIR + settings_manager.GetString( settings::SettingId::certificate_file); - root_cert_file_ = DATA_DIR + settings::SettingsManager::GetString( + root_cert_file_ = DATA_DIR + settings_manager.GetString( settings::SettingId::root_cert_file); } void PelotonServer::SSLInit() { - if (!settings::SettingsManager::GetBool(settings::SettingId::ssl)) { + if (!settings::SettingsManager::GetInstance().GetBool( + settings::SettingId::ssl)) { SetSSLLevel(SSLLevel::SSL_DISABLE); return; } @@ -189,9 +191,10 @@ void PelotonServer::SSLInit() { } PelotonServer::PelotonServer() { - port_ = settings::SettingsManager::GetInt(settings::SettingId::port); - max_connections_ = - settings::SettingsManager::GetInt(settings::SettingId::max_connections); + auto &settings_manager = settings::SettingsManager::GetInstance(); + port_ = settings_manager.GetInt(settings::SettingId::port); + max_connections_ = settings_manager.GetInt( + settings::SettingId::max_connections); // For logging purposes // event_enable_debug_mode(); @@ -237,7 +240,7 @@ void PelotonServer::TrySslOperation(int (*func)(Ts...), Ts... arg) { PelotonServer &PelotonServer::SetupServer() { // This line is critical to performance for some reason evthread_use_pthreads(); - if (settings::SettingsManager::GetString( + if (settings::SettingsManager::GetInstance().GetString( settings::SettingId::socket_family) != "AF_INET") throw ConnectionException("Unsupported socket family"); @@ -269,9 +272,10 @@ PelotonServer &PelotonServer::SetupServer() { } void PelotonServer::ServerLoop() { - if (settings::SettingsManager::GetBool(settings::SettingId::rpc_enabled)) { - int rpc_port = - settings::SettingsManager::GetInt(settings::SettingId::rpc_port); + auto &settings_manager = settings::SettingsManager::GetInstance(); + if (settings_manager.GetBool(settings::SettingId::rpc_enabled)) { + int rpc_port = settings_manager.GetInt( + settings::SettingId::rpc_port); std::string address = "127.0.0.1:" + std::to_string(rpc_port); auto rpc_task = std::make_shared(address.c_str()); DedicatedThreadRegistry::GetInstance() diff --git a/src/network/postgres_protocol_handler.cpp b/src/network/postgres_protocol_handler.cpp index 6f03a617667..37dbb271c8b 100644 --- a/src/network/postgres_protocol_handler.cpp +++ b/src/network/postgres_protocol_handler.cpp @@ -383,7 +383,7 @@ void PostgresProtocolHandler::ExecParseMessage(InputPacket *pkt) { statement->SetParamTypes(param_types); // Stat - if (static_cast(settings::SettingsManager::GetInt( + if (static_cast(settings::SettingsManager::GetInstance().GetInt( settings::SettingId::stats_mode)) != StatsType::INVALID) { // Make a copy of param types for stat collection stats::QueryMetric::QueryParamBuf query_type_buf; @@ -529,7 +529,7 @@ void PostgresProtocolHandler::ExecBindMessage(InputPacket *pkt) { } std::shared_ptr param_stat(nullptr); - if (static_cast(settings::SettingsManager::GetInt( + if (static_cast(settings::SettingsManager::GetInstance().GetInt( settings::SettingId::stats_mode)) != StatsType::INVALID && num_params > 0) { // Make a copy of format for stat collection diff --git a/src/optimizer/plan_generator.cpp b/src/optimizer/plan_generator.cpp index fd1824360e3..97eea1d6b8d 100644 --- a/src/optimizer/plan_generator.cpp +++ b/src/optimizer/plan_generator.cpp @@ -91,7 +91,8 @@ void PlanGenerator::Visit(const PhysicalSeqScan *op) { op->table_->GetDatabaseOid(), op->table_->GetTableOid()); // Check if we should do a parallel scan - bool parallel_exec_enabled = settings::SettingsManager::GetBool( + auto &setting_manager = settings::SettingsManager::GetInstance(); + bool parallel_exec_enabled = setting_manager.GetBool( settings::SettingId::parallel_execution); bool parallel_scan = parallel_exec_enabled; @@ -101,7 +102,7 @@ void PlanGenerator::Visit(const PhysicalSeqScan *op) { auto num_tilegroups = data_table->GetTileGroupCount(); auto num_tuples = data_table->GetTupleCount(); auto min_parallel_table_scan_size = - static_cast(settings::SettingsManager::GetInt( + static_cast(setting_manager.GetInt( settings::SettingId::min_parallel_table_scan_size)); parallel_scan = (num_tilegroups > 1 && num_tuples > min_parallel_table_scan_size); @@ -326,7 +327,7 @@ void PlanGenerator::Visit(const PhysicalInnerHashJoin *op) { auto join_plan = unique_ptr(new planner::HashJoinPlan( JoinType::INNER, move(join_predicate), move(proj_info), proj_schema, - left_keys, right_keys, settings::SettingsManager::GetBool( + left_keys, right_keys, settings::SettingsManager::GetInstance().GetBool( settings::SettingId::hash_join_bloom_filter))); join_plan->AddChild(move(children_plans_[0])); diff --git a/src/optimizer/query_to_operator_transformer.cpp b/src/optimizer/query_to_operator_transformer.cpp index c539826ae53..dbbc6452906 100644 --- a/src/optimizer/query_to_operator_transformer.cpp +++ b/src/optimizer/query_to_operator_transformer.cpp @@ -33,8 +33,9 @@ QueryToOperatorTransformer::QueryToOperatorTransformer( concurrency::TransactionContext *txn) : txn_(txn), get_id(0), - enable_predicate_push_down_(settings::SettingsManager::GetBool( - settings::SettingId::predicate_push_down)) {} + enable_predicate_push_down_( + settings::SettingsManager::GetInstance().GetBool( + settings::SettingId::predicate_push_down)) {} std::shared_ptr QueryToOperatorTransformer::ConvertToOpExpression(parser::SQLStatement *op) { output_expr_ = nullptr; diff --git a/src/settings/settings_manager.cpp b/src/settings/settings_manager.cpp index 18de619defd..97c8ed9b5a5 100644 --- a/src/settings/settings_manager.cpp +++ b/src/settings/settings_manager.cpp @@ -31,60 +31,182 @@ namespace peloton { namespace settings { -int32_t SettingsManager::GetInt(SettingId id) { - return GetInstance().GetValue(id).GetAs(); +SettingsManager &SettingsManager::GetInstance() { + static SettingsManager settings_manager; + return settings_manager; +} + +/** @brief Get setting value as integer. + * @param ID to get the setting. + * @return Setting value + */ +int32_t SettingsManager::GetInt(SettingId id) const { + return GetValue(id).GetAs(); } -double SettingsManager::GetDouble(SettingId id) { - return GetInstance().GetValue(id).GetAs(); +/** @brief Get setting value as double. + * @param ID to get the setting. + * @return Setting value + */ +double SettingsManager::GetDouble(SettingId id) const { + return GetValue(id).GetAs(); } -bool SettingsManager::GetBool(SettingId id) { - return GetInstance().GetValue(id).GetAs(); +/** @brief Get setting value as boolean. + * @param ID to get the setting. + * @return Setting value + */ +bool SettingsManager::GetBool(SettingId id) const { + return GetValue(id).GetAs(); } -std::string SettingsManager::GetString(SettingId id) { - return GetInstance().GetValue(id).ToString(); +/** @brief Get setting value as string. + * @param ID to get the setting. + * @return Setting value + */ +std::string SettingsManager::GetString(SettingId id) const { + return GetValue(id).ToString(); +} + +/** @brief Get setting value as Value object. + * @param ID to get the setting. + * @return Setting value + */ +type::Value SettingsManager::GetValue(SettingId id) const { + // TODO: Look up the value from catalog + // Because querying a catalog table needs to create a new transaction and + // creating transaction needs to get setting values, + // it will be a infinite recursion here. + + auto param = settings_.find(id); + return param->second.value; } -void SettingsManager::SetInt(SettingId id, int32_t value) { - GetInstance().SetValue(id, type::ValueFactory::GetIntegerValue(value)); +/** @brief Set setting value as integer. + * @param id ID to set the setting. + * @param value Value set to the setting. + * @param set_default Set the value to default in addition if true. + * @param txn TransactionContext for the catalog control. + * This has to be set after catalog initialization. + */ +void SettingsManager::SetInt(SettingId id, int32_t value, bool set_default, + concurrency::TransactionContext *txn) { + SetValue(id, type::ValueFactory::GetIntegerValue(value), set_default, txn); } -void SettingsManager::SetBool(SettingId id, bool value) { - GetInstance().SetValue(id, type::ValueFactory::GetBooleanValue(value)); +/** @brief Set setting value as double. + * @param id ID to set the setting. + * @param value Value set to the setting. + * @param set_default Set the value to default in addition if true. + * @param txn TransactionContext for the catalog control. + * This has to be set after catalog initialization. + */ +void SettingsManager::SetDouble(SettingId id, double value, bool set_default, + concurrency::TransactionContext *txn) { + SetValue(id, type::ValueFactory::GetDecimalValue(value), set_default, txn); } -void SettingsManager::SetString(SettingId id, const std::string &value) { - GetInstance().SetValue(id, type::ValueFactory::GetVarcharValue(value)); +/** @brief Set setting value as boolean. + * @param id ID to set the setting. + * @param value Value set to the setting. + * @param set_default Set the value to default in addition if true. + * @param txn TransactionContext for the catalog control. + * This has to be set after catalog initialization. + */ +void SettingsManager::SetBool(SettingId id, bool value, bool set_default, + concurrency::TransactionContext *txn) { + SetValue(id, type::ValueFactory::GetBooleanValue(value), set_default, txn); } -SettingsManager &SettingsManager::GetInstance() { - static SettingsManager settings_manager; - return settings_manager; +/** @brief Set setting value as string. + * @param id ID to set the setting. + * @param value Value set to the setting. + * @param set_default Set the value to default in addition if true. + * @param txn TransactionContext for the catalog control. + * This has to be set after catalog initialization. + */ +void SettingsManager::SetString(SettingId id, const std::string &value, + bool set_default, + concurrency::TransactionContext *txn) { + SetValue(id, type::ValueFactory::GetVarcharValue(value), set_default, txn); +} + +/** @brief Set setting value as Value object. + * @param id ID to set the setting. + * @param value Value set to the setting. + * @param set_default Set the value to default in addition if true. + * @param txn TransactionContext for the catalog control. + * This has to be set after catalog initialization. + */ +void SettingsManager::SetValue(SettingId id, const type::Value &value, + bool set_default, + concurrency::TransactionContext *txn) { + auto param = settings_.find(id); + + // Check min-max bound if value is a following type + if ((value.GetTypeId() == type::TypeId::BIGINT || + value.GetTypeId() == type::TypeId::INTEGER || + value.GetTypeId() == type::TypeId::SMALLINT || + value.GetTypeId() == type::TypeId::TINYINT || + value.GetTypeId() == type::TypeId::DECIMAL) && + !value.CompareBetweenInclusive(param->second.min_value, + param->second.max_value)) { + throw SettingsException("Value given for \"" + param->second.name + + "\" is not in its min-max bounds (" + + param->second.min_value.ToString() + "-" + + param->second.max_value.ToString() + ")"); + } + + // Catalog update if initialized + if (catalog_initialized_) { + PELOTON_ASSERT(txn != nullptr); + if (!UpdateCatalog(param->second.name, value, set_default, txn)) { + throw SettingsException("failed to set value " + value.ToString() + + " to " + param->second.name); + } + } + + // Set value + param->second.value = value; + + // Set default_value if set_default is true + if (set_default) { + param->second.default_value = value; + } +} + +/** @brief Reset a setting value to default value. + * @param id ID to reset the setting. + * @param txn TransactionContext for the catalog control. + * This has to be set after catalog initialization. + */ +void SettingsManager::ResetValue(SettingId id, + concurrency::TransactionContext *txn) { + auto param = settings_.find(id); + auto default_value = param->second.default_value; + + // Catalog update if initialized + if (catalog_initialized_) { + PELOTON_ASSERT(txn != nullptr); + if (!UpdateCatalog(param->second.name, default_value, false, txn)) { + throw SettingsException("failed to set value " + + default_value.ToString() + " to " + + param->second.name); + } + } + + // set default_value into the setting value + param->second.value = default_value; } void SettingsManager::InitializeCatalog() { - auto &settings_catalog = peloton::catalog::SettingsCatalog::GetInstance(); + if (catalog_initialized_) return; auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); auto txn = txn_manager.BeginTransaction(); - type::AbstractPool *pool = pool_.get(); for (auto s : settings_) { - // TODO: Use Update instead Delete & Insert - settings_catalog.DeleteSetting(txn, s.second.name); - if (!settings_catalog.InsertSetting(txn, - s.second.name, - s.second.value.ToString(), - s.second.value.GetTypeId(), - s.second.desc, - "", - "", - s.second.default_value.ToString(), - s.second.is_mutable, - s.second.is_persistent, - pool)) { + if (!InsertCatalog(s.second, txn)) { txn_manager.AbortTransaction(txn); throw SettingsException("failed to initialize catalog pg_settings on " + s.second.name); @@ -94,6 +216,30 @@ void SettingsManager::InitializeCatalog() { catalog_initialized_ = true; } +/** @brief Refresh all setting values from setting catalog. + * @param txn TransactionContext for the catalog control. + */ +void SettingsManager::UpdateSettingListFromCatalog( + concurrency::TransactionContext *txn) { + auto &settings_catalog = catalog::SettingsCatalog::GetInstance(txn); + + // Update each setting value from pg_settings + for (auto param = settings_.begin(); param != settings_.end(); param++) { + auto setting_entry = + settings_catalog.GetSettingsCatalogEntry(txn, param->second.name); + + if (setting_entry != nullptr) { + // Set the setting value and the default value + param->second.value = setting_entry->GetValue(); + param->second.default_value = setting_entry->GetDefaultValue(); + } else { + LOG_ERROR("Setting %s can't be found within SettingsCatalog", + param->second.name.c_str()); + PELOTON_ASSERT(false); + } + } +} + const std::string SettingsManager::GetInfo() const { const uint32_t box_width = 72; const std::string title = "PELOTON SETTINGS"; @@ -137,65 +283,68 @@ void SettingsManager::DefineSetting(SettingId id, const std::string &name, } // Only below types support min-max bound checking - if (value.GetTypeId() == type::TypeId::INTEGER || + if (value.GetTypeId() == type::TypeId::BIGINT || + value.GetTypeId() == type::TypeId::INTEGER || value.GetTypeId() == type::TypeId::SMALLINT || value.GetTypeId() == type::TypeId::TINYINT || value.GetTypeId() == type::TypeId::DECIMAL) { if (!value.CompareBetweenInclusive(min_value, max_value)) - throw SettingsException("Value given for \"" + name + - "\" is not in its min-max bounds (" + - min_value.ToString() + "-" + - max_value.ToString() + ")"); + throw SettingsException( + "Value given for \"" + name + "\" is not in its min-max bounds (" + + min_value.ToString() + "-" + max_value.ToString() + ")"); } settings_.emplace(id, Param(name, value, description, default_value, - is_mutable, is_persistent)); + min_value, max_value, is_mutable, is_persistent)); } -type::Value SettingsManager::GetValue(SettingId id) { - // TODO: Look up the value from catalog - // Because querying a catalog table needs to create a new transaction and - // creating transaction needs to get setting values, - // it will be a infinite recursion here. - - auto param = settings_.find(id); - return param->second.value; -} +/** @brief Insert a setting information into setting catalog. + * @param param Setting information. + * @param txn TransactionContext for the catalog control. + * @return True if success, or false + */ +bool SettingsManager::InsertCatalog(const Param ¶m, + concurrency::TransactionContext *txn) { + auto &settings_catalog = catalog::SettingsCatalog::GetInstance(); -void SettingsManager::SetValue(SettingId id, const type::Value &value) { - auto param = settings_.find(id); - Param new_param = param->second; - new_param.value = value; - if (catalog_initialized_) { - if (!InsertIntoCatalog(new_param)) { - throw SettingsException("failed to set value " + param->second.name); - } + // Check a same setting is not existed + if (settings_catalog.GetSettingsCatalogEntry(txn, param.name) != nullptr) { + LOG_ERROR("The setting %s is already existed", param.name.c_str()); + return false; } - param->second.value = value; -} -bool SettingsManager::InsertIntoCatalog(const Param ¶m) { - auto &settings_catalog = catalog::SettingsCatalog::GetInstance(); - auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); - auto txn = txn_manager.BeginTransaction(); - type::AbstractPool *pool = pool_.get(); - // TODO: Use Update instead Delete & Insert - settings_catalog.DeleteSetting(txn, param.name); if (!settings_catalog.InsertSetting(txn, param.name, param.value.ToString(), param.value.GetTypeId(), param.desc, - "", - "", + param.min_value.ToString(), + param.max_value.ToString(), param.default_value.ToString(), param.is_mutable, param.is_persistent, - pool)) { - txn_manager.AbortTransaction(txn); + pool_.get())) { + return false; + } + return true; +} + +/** @brief Update a setting value within setting catalog. + * @param name Setting name to be updated. + * @param value Setting value to be set as a new value. + * @param set_default a flag whether update the default value. + * @param txn TransactionContext for the catalog control. + * @return True if success, or false + */ +bool SettingsManager::UpdateCatalog(const std::string &name, + const type::Value &value, bool set_default, + concurrency::TransactionContext *txn) { + auto &settings_catalog = catalog::SettingsCatalog::GetInstance(); + if (!settings_catalog.UpdateSettingValue(txn, name, + value.ToString(), + set_default)) { return false; } - txn_manager.CommitTransaction(txn); return true; } diff --git a/src/traffic_cop/traffic_cop.cpp b/src/traffic_cop/traffic_cop.cpp index bbf0846ac9a..327f0df3d83 100644 --- a/src/traffic_cop/traffic_cop.cpp +++ b/src/traffic_cop/traffic_cop.cpp @@ -305,7 +305,8 @@ std::shared_ptr TrafficCop::PrepareStatement( tcop_txn_state_.emplace(txn, ResultType::SUCCESS); } - if (settings::SettingsManager::GetBool(settings::SettingId::brain)) { + if (settings::SettingsManager::GetInstance().GetBool( + settings::SettingId::brain)) { tcop_txn_state_.top().first->AddQueryString(query_string.c_str()); } @@ -557,7 +558,7 @@ ResultType TrafficCop::ExecuteStatement( const std::vector &result_format, std::vector &result, size_t thread_id) { // TODO(Tianyi) Further simplify this API - if (static_cast(settings::SettingsManager::GetInt( + if (static_cast(settings::SettingsManager::GetInstance().GetInt( settings::SettingId::stats_mode)) != StatsType::INVALID) { stats::BackendStatsContext::GetInstance()->InitQueryMetric( statement, std::move(param_stats)); diff --git a/test/brain/query_logger_test.cpp b/test/brain/query_logger_test.cpp index 301e3408dbd..2800e42adca 100644 --- a/test/brain/query_logger_test.cpp +++ b/test/brain/query_logger_test.cpp @@ -22,7 +22,9 @@ namespace test { class QueryLoggerTests : public PelotonTest { protected: void SetUp() override { - settings::SettingsManager::SetBool(settings::SettingId::brain, true); + settings::SettingsManager::GetInstance().SetBool( + settings::SettingId::brain, true); + PelotonInit::Initialize(); // query to check that logging is done diff --git a/test/settings/settings_manager_test.cpp b/test/settings/settings_manager_test.cpp index 251b057648a..a0a87675e20 100644 --- a/test/settings/settings_manager_test.cpp +++ b/test/settings/settings_manager_test.cpp @@ -33,27 +33,31 @@ TEST_F(SettingsManagerTests, InitializationTest) { // test port (int) auto txn = txn_manager.BeginTransaction(); - int32_t port = settings::SettingsManager::GetInt(settings::SettingId::port); + int32_t port = config_manager.GetInt(settings::SettingId::port); int32_t port_default = - atoi(settings_catalog.GetDefaultValue(txn, "port").c_str()); + settings_catalog.GetSettingsCatalogEntry(txn, "port") + ->GetDefaultValue() + .GetAs(); txn_manager.CommitTransaction(txn); EXPECT_EQ(port, port_default); // test socket_family (string) txn = txn_manager.BeginTransaction(); std::string socket_family = - settings::SettingsManager::GetString(settings::SettingId::socket_family); + config_manager.GetString(settings::SettingId::socket_family); std::string socket_family_default = - settings_catalog.GetDefaultValue(txn, "socket_family"); + settings_catalog.GetSettingsCatalogEntry(txn, "socket_family") + ->GetDefaultValue().ToString(); txn_manager.CommitTransaction(txn); EXPECT_EQ(socket_family, socket_family_default); // test indextuner (bool) txn = txn_manager.BeginTransaction(); bool index_tuner = - settings::SettingsManager::GetBool(settings::SettingId::index_tuner); + config_manager.GetBool(settings::SettingId::index_tuner); bool index_tuner_default = - ("true" == settings_catalog.GetDefaultValue(txn, "index_tuner")); + settings_catalog.GetSettingsCatalogEntry(txn, "index_tuner") + ->GetDefaultValue().IsTrue(); txn_manager.CommitTransaction(txn); EXPECT_EQ(index_tuner, index_tuner_default); } @@ -68,59 +72,103 @@ TEST_F(SettingsManagerTests, ModificationTest) { config_manager.InitializeCatalog(); - // modify int + // modify int (value only) auto txn = txn_manager.BeginTransaction(); - int32_t value1 = settings::SettingsManager::GetInt(settings::SettingId::port); - int32_t value2 = atoi(settings_catalog.GetSettingValue(txn, "port").c_str()); + int32_t value1 = config_manager.GetInt(settings::SettingId::port); + int32_t value2 = + settings_catalog.GetSettingsCatalogEntry(txn, "port") + ->GetValue() + .GetAs(); EXPECT_EQ(value1, value2); txn_manager.CommitTransaction(txn); - settings::SettingsManager::SetInt(settings::SettingId::port, 12345); - txn = txn_manager.BeginTransaction(); - int32_t value3 = settings::SettingsManager::GetInt(settings::SettingId::port); - int32_t value4 = atoi(settings_catalog.GetSettingValue(txn, "port").c_str()); + config_manager.SetInt(settings::SettingId::port, 12345, false, txn); + int32_t value3 = config_manager.GetInt(settings::SettingId::port); + int32_t value4 = + settings_catalog.GetSettingsCatalogEntry(txn, "port") + ->GetValue() + .GetAs(); EXPECT_EQ(value3, 12345); EXPECT_EQ(value3, value4); txn_manager.CommitTransaction(txn); - // modify bool txn = txn_manager.BeginTransaction(); - bool value5 = - settings::SettingsManager::GetBool(settings::SettingId::index_tuner); - bool value6 = - ("true" == settings_catalog.GetSettingValue(txn, "index_tuner")); - EXPECT_EQ(value5, value6); + config_manager.ResetValue(settings::SettingId::port, txn); + int32_t value5 = config_manager.GetInt(settings::SettingId::port); + int32_t value6 = + settings_catalog.GetSettingsCatalogEntry(txn, "port") + ->GetValue() + .GetAs(); + EXPECT_EQ(value1, value5); + EXPECT_EQ(value2, value6); txn_manager.CommitTransaction(txn); - settings::SettingsManager::SetBool(settings::SettingId::index_tuner, true); - + // modify bool (value only) txn = txn_manager.BeginTransaction(); - bool value7 = - settings::SettingsManager::GetBool(settings::SettingId::index_tuner); + bool value7 = config_manager.GetBool(settings::SettingId::index_tuner); bool value8 = - ("true" == settings_catalog.GetSettingValue(txn, "index_tuner")); - EXPECT_TRUE(value7); + settings_catalog.GetSettingsCatalogEntry(txn, "index_tuner") + ->GetValue() + .IsTrue(); EXPECT_EQ(value7, value8); txn_manager.CommitTransaction(txn); - // modify string txn = txn_manager.BeginTransaction(); - std::string value9 = - settings::SettingsManager::GetString(settings::SettingId::socket_family); - std::string value10 = settings_catalog.GetSettingValue(txn, "socket_family"); + config_manager.SetBool(settings::SettingId::index_tuner, true, false, txn); + bool value9 = config_manager.GetBool(settings::SettingId::index_tuner); + bool value10 = + settings_catalog.GetSettingsCatalogEntry(txn, "index_tuner") + ->GetValue() + .IsTrue(); + EXPECT_TRUE(value9); EXPECT_EQ(value9, value10); txn_manager.CommitTransaction(txn); - settings::SettingsManager::SetString(settings::SettingId::socket_family, - "test"); + txn = txn_manager.BeginTransaction(); + config_manager.ResetValue(settings::SettingId::index_tuner, txn); + bool value11 = config_manager.GetBool(settings::SettingId::index_tuner); + bool value12 = + settings_catalog.GetSettingsCatalogEntry(txn, "index_tuner") + ->GetValue() + .IsTrue(); + EXPECT_EQ(value7, value11); + EXPECT_EQ(value8, value12); + txn_manager.CommitTransaction(txn); + + // modify string (value + default value) + txn = txn_manager.BeginTransaction(); + std::string value13 = + config_manager.GetString(settings::SettingId::socket_family); + std::string value14 = + settings_catalog.GetSettingsCatalogEntry(txn, "socket_family") + ->GetValue() + .ToString(); + EXPECT_EQ(value13, value14); + txn_manager.CommitTransaction(txn); + + txn = txn_manager.BeginTransaction(); + config_manager.SetString(settings::SettingId::socket_family, "test", true, txn); + std::string value15 = + config_manager.GetString(settings::SettingId::socket_family); + std::string value16 = + settings_catalog.GetSettingsCatalogEntry(txn, "socket_family") + ->GetValue() + .ToString(); + EXPECT_EQ(value15, "test"); + EXPECT_EQ(value16, value16); + txn_manager.CommitTransaction(txn); txn = txn_manager.BeginTransaction(); - std::string value11 = - settings::SettingsManager::GetString(settings::SettingId::socket_family); - std::string value12 = settings_catalog.GetSettingValue(txn, "socket_family"); - EXPECT_EQ(value11, "test"); - EXPECT_EQ(value11, value12); + config_manager.ResetValue(settings::SettingId::index_tuner, txn); + std::string value17 = + config_manager.GetString(settings::SettingId::socket_family); + std::string value18 = + settings_catalog.GetSettingsCatalogEntry(txn, "socket_family") + ->GetValue() + .ToString(); + EXPECT_EQ(value15, value17); + EXPECT_EQ(value16, value18); txn_manager.CommitTransaction(txn); } diff --git a/test/statistics/stats_test.cpp b/test/statistics/stats_test.cpp index 792c4317b38..e68bc01019b 100644 --- a/test/statistics/stats_test.cpp +++ b/test/statistics/stats_test.cpp @@ -44,8 +44,12 @@ class StatsTests : public PelotonTest {}; // Launch the aggregator thread manually void LaunchAggregator(int64_t stat_interval) { - settings::SettingsManager::SetInt(settings::SettingId::stats_mode, - static_cast(StatsType::ENABLE)); + auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); + auto txn = txn_manager.BeginTransaction(); + settings::SettingsManager::GetInstance() + .SetInt(settings::SettingId::stats_mode, + static_cast(StatsType::ENABLE), txn); + txn_manager.CommitTransaction(txn); auto &aggregator = peloton::stats::StatsAggregator::GetInstance(stat_interval);