#pragma once #include #include #include #include #include #include #include #include #include /** Maintains a list of currently running merges. * For implementation of system.merges table. */ namespace CurrentMetrics { extern const Metric Merge; } namespace DB { struct MergeInfo { std::string database; std::string table; std::string result_part_name; Array source_part_names; Float64 elapsed; Float64 progress; UInt64 num_parts; UInt64 total_size_bytes_compressed; UInt64 total_size_marks; UInt64 bytes_read_uncompressed; UInt64 bytes_written_uncompressed; UInt64 rows_read; UInt64 rows_written; UInt64 columns_written; UInt64 memory_usage; UInt64 thread_number; }; struct MergeListElement : boost::noncopyable { const std::string database; const std::string table; const std::string result_part_name; Stopwatch watch; Float64 progress{}; UInt64 num_parts{}; Names source_part_names; UInt64 total_size_bytes_compressed{}; UInt64 total_size_marks{}; std::atomic bytes_read_uncompressed{}; std::atomic bytes_written_uncompressed{}; /// In case of Vertical algorithm they are actual only for primary key columns std::atomic rows_read{}; std::atomic rows_written{}; /// Updated only for Vertical algorithm std::atomic columns_written{}; MemoryTracker memory_tracker; MemoryTracker * background_pool_task_memory_tracker; /// Poco thread number used in logs UInt32 thread_number; MergeListElement(const std::string & database, const std::string & table, const std::string & result_part_name, const MergeTreeData::DataPartsVector & source_parts); MergeInfo getInfo() const; ~MergeListElement(); }; class MergeList; class MergeListEntry { MergeList & list; using container_t = std::list; container_t::iterator it; CurrentMetrics::Increment num_merges {CurrentMetrics::Merge}; public: MergeListEntry(const MergeListEntry &) = delete; MergeListEntry & operator=(const MergeListEntry &) = delete; MergeListEntry(MergeList & list, const container_t::iterator it) : list(list), it{it} {} ~MergeListEntry(); MergeListElement * operator->() { return &*it; } }; class MergeList { friend class MergeListEntry; using container_t = std::list; using info_container_t = std::list; mutable std::mutex mutex; container_t merges; public: using Entry = MergeListEntry; using EntryPtr = std::unique_ptr; template EntryPtr insert(Args &&... args) { std::lock_guard lock{mutex}; return std::make_unique(*this, merges.emplace(merges.end(), std::forward(args)...)); } info_container_t get() const { std::lock_guard lock{mutex}; info_container_t res; for (const auto & merge_element : merges) res.emplace_back(merge_element.getInfo()); return res; } }; inline MergeListEntry::~MergeListEntry() { std::lock_guard lock{list.mutex}; list.merges.erase(it); } }